示例#1
0
/* Caller may need to use label_get_handler to create label struct! */
int label_write(struct device *dev, struct label *label)
{
#pragma pack(8)
        char buf[LABEL_SIZE]; //__attribute((aligned(8)));
#pragma pack()
        struct label_header *lh = (struct label_header *) buf;
        int r = 1;

        if (!label->labeller->ops->write) {
                log_err("Label handler does not support label writes");
                return 0;
        }

        if ((LABEL_SIZE + (label->sector << SECTOR_SHIFT)) > LABEL_SCAN_SIZE) {
                log_error("Label sector %" PRIu64 " beyond range (%ld)",
                          label->sector, LABEL_SCAN_SECTORS);
                return 0;
        }

        memset(buf, 0, LABEL_SIZE);

        strncpy((char *)lh->id, LABEL_ID, sizeof(lh->id));
        lh->sector_xl = xlate64(label->sector);
        lh->offset_xl = xlate32(sizeof(*lh));

        if (!(label->labeller->ops->write)(label, buf)) {
                stack;
                return 0;
        }

        lh->crc_xl = xlate32(calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
                                      ((char *) &lh->offset_xl - (char *) lh)));
                                      //((void *) &lh->offset_xl - (void *) lh)));

        if (!dev_open(dev)) {
                stack;
                return 0;
        }

        log_info("%s: Writing label to sector %" PRIu64, dev_name(dev),
                 label->sector);
        if (!dev_write(dev, label->sector << SECTOR_SHIFT, LABEL_SIZE, buf)) {
                log_debug("Failed to write label to %s", dev_name(dev));
                r = 0;
        }

        if (!dev_close(dev))
                stack;

        return r;
}
示例#2
0
文件: dev-md.c 项目: Jajcus/lvm2
static int _dev_has_md_magic(struct device *dev, uint64_t sb_offset)
{
    uint32_t md_magic;

    /* Version 1 is little endian; version 0.90.0 is machine endian */
    if (dev_read(dev, sb_offset, sizeof(uint32_t), &md_magic) &&
            ((md_magic == xlate32(MD_SB_MAGIC)) ||
             (md_magic == MD_SB_MAGIC)))
        return 1;

    return 0;
}
示例#3
0
static void __update_lvmcache(const struct format_type *fmt,
			      struct disk_list *dl,
			      struct device *dev, const char *vgid,
			      unsigned exported)
{
	struct lvmcache_info *info;
	const char *vgname = *((char *)dl->pvd.vg_name) ?
			     (char *)dl->pvd.vg_name : fmt->orphan_vg_name;

	if (!(info = lvmcache_add(fmt->labeller, (char *)dl->pvd.pv_uuid, dev,
				  vgname, vgid, exported ? EXPORTED_VG : 0))) {
		stack;
		return;
	}

	lvmcache_set_device_size(info, ((uint64_t)xlate32(dl->pvd.pv_size)) << SECTOR_SHIFT);
	lvmcache_del_mdas(info);
	lvmcache_make_valid(info);
}
示例#4
0
static void __update_lvmcache(const struct format_type *fmt,
			      struct disk_list *dl,
			      struct device *dev, const char *vgid,
			      unsigned exported)
{
	struct lvmcache_info *info;
	const char *vgname = *((char *)dl->pvd.vg_name) ?
			     (char *)dl->pvd.vg_name : fmt->orphan_vg_name;

	if (!(info = lvmcache_add(fmt->labeller, (char *)dl->pvd.pv_uuid, dev,
				  vgname, vgid, exported ? EXPORTED_VG : 0))) {
		stack;
		return;
	}

	info->device_size = xlate32(dl->pvd.pv_size) << SECTOR_SHIFT;
	dm_list_init(&info->mdas);
	info->status &= ~CACHE_INVALID;
}
示例#5
0
static struct labeller *_find_labeller(struct device *dev, char *buf,
                                       uint64_t *label_sector,
                                       uint64_t scan_sector)
{
#pragma pack(8)
        char readbuf[LABEL_SCAN_SIZE];
#pragma pack()
        struct labeller_i *li;
        struct labeller *r = NULL;
        struct label_header *lh;
        struct lvmcache_info *info;
        uint64_t sector;
        int found = 0;
        //char readbuf[LABEL_SCAN_SIZE] __attribute((aligned(8)));

        if (!dev_read(dev, scan_sector << SECTOR_SHIFT,
                      LABEL_SCAN_SIZE, readbuf)) {
                log_debug("%s: Failed to read label area", dev_name(dev));
                goto out;
        }

        /* Scan a few sectors for a valid label */
        for (sector = 0; sector < LABEL_SCAN_SECTORS;
             sector += LABEL_SIZE >> SECTOR_SHIFT) {
                lh = (struct label_header *) (readbuf +
                                              (sector << SECTOR_SHIFT));

                if (!strncmp((char *)lh->id, LABEL_ID, sizeof(lh->id))) {
                        if (found) {
                                log_error("Ignoring additional label on %s at "
                                          "sector %" PRIu64, dev_name(dev),
                                          sector + scan_sector);
                        }
                        if (xlate64(lh->sector_xl) != sector + scan_sector) {
                                log_info("%s: Label for sector %" PRIu64
                                         " found at sector %" PRIu64
                                         " - ignoring", dev_name(dev),
                                         xlate64(lh->sector_xl),
                                         sector + scan_sector);
                                continue;
                        }
                        if (calc_crc(INITIAL_CRC, &lh->offset_xl, LABEL_SIZE -
                                     ((char *) &lh->offset_xl - (char *) lh)) !=
                                     //((void *) &lh->offset_xl - (void *) lh)) !=
                            xlate32(lh->crc_xl)) {
                                log_info("Label checksum incorrect on %s - "
                                         "ignoring", dev_name(dev));
                                continue;
                        }
                        if (found)
                                continue;
                }

                //list_iterate_items(li, &_labellers) {
                list_iterate_items(li, struct labeller_i, &_labellers) {
                        if (li->l->ops->can_handle(li->l, (char *) lh,
                                                   sector + scan_sector)) {
                                log_very_verbose("%s: %s label detected",
                                                 dev_name(dev), li->name);
                                if (found) {
                                        log_error("Ignoring additional label "
                                                  "on %s at sector %" PRIu64,
                                                  dev_name(dev),
                                                  sector + scan_sector);
                                        continue;
                                }
                                r = li->l;
                                memcpy(buf, lh, LABEL_SIZE);
                                if (label_sector)
                                        *label_sector = sector + scan_sector;
                                found = 1;
                                break;
                        }
                }
        }

      out:
        if (!found) {
                if ((info = info_from_pvid(dev->pvid)))
                        lvmcache_update_vgname_and_id(info, ORPHAN, ORPHAN,
                                                      0, NULL);
                log_very_verbose("%s: No label detected", dev_name(dev));
        }

        return r;
}