static void label_label(struct gctl_req *req) { struct g_label_metadata md; const char *name, *label; u_char sector[512]; int error, nargs; nargs = gctl_get_int(req, "nargs"); if (nargs != 2) { gctl_error(req, "Invalid number of arguments."); return; } /* * Clear last sector first to spoil all components if device exists. */ name = gctl_get_ascii(req, "arg1"); error = g_metadata_clear(name, NULL); if (error != 0) { gctl_error(req, "Can't store metadata on %s: %s.", name, strerror(error)); return; } strlcpy(md.md_magic, G_LABEL_MAGIC, sizeof(md.md_magic)); md.md_version = G_LABEL_VERSION; label = gctl_get_ascii(req, "arg0"); strlcpy(md.md_label, label, sizeof(md.md_label)); md.md_provsize = g_get_mediasize(name); if (md.md_provsize == 0) { gctl_error(req, "Can't get mediasize of %s: %s.", name, strerror(errno)); return; } /* * Ok, store metadata. */ label_metadata_encode(&md, sector); error = g_metadata_store(name, sector, sizeof(sector)); if (error != 0) { fprintf(stderr, "Can't store metadata on %s: %s.\n", name, strerror(error)); gctl_error(req, "Not done."); } if (verbose) printf("Metadata value stored on %s.\n", name); }
static void stripe_label(struct gctl_req *req) { struct g_stripe_metadata md; intmax_t stripesize; off_t compsize, msize; u_char sector[512]; unsigned ssize, secsize; const char *name; int error, i, nargs, hardcode; nargs = gctl_get_int(req, "nargs"); if (nargs < 3) { gctl_error(req, "Too few arguments."); return; } hardcode = gctl_get_int(req, "hardcode"); /* * Clear last sector first to spoil all components if device exists. */ compsize = 0; secsize = 0; for (i = 1; i < nargs; i++) { name = gctl_get_ascii(req, "arg%d", i); msize = g_get_mediasize(name); ssize = g_get_sectorsize(name); if (msize == 0 || ssize == 0) { gctl_error(req, "Can't get informations about %s: %s.", name, strerror(errno)); return; } msize -= ssize; if (compsize == 0 || (compsize > 0 && msize < compsize)) compsize = msize; if (secsize == 0) secsize = ssize; else secsize = g_lcm(secsize, ssize); error = g_metadata_clear(name, NULL); if (error != 0) { gctl_error(req, "Can't store metadata on %s: %s.", name, strerror(error)); return; } } strlcpy(md.md_magic, G_STRIPE_MAGIC, sizeof(md.md_magic)); md.md_version = G_STRIPE_VERSION; name = gctl_get_ascii(req, "arg0"); strlcpy(md.md_name, name, sizeof(md.md_name)); md.md_id = arc4random(); md.md_all = nargs - 1; stripesize = gctl_get_intmax(req, "stripesize"); if ((stripesize % secsize) != 0) { gctl_error(req, "Stripesize should be multiple of %u.", secsize); return; } md.md_stripesize = stripesize; /* * Ok, store metadata. */ for (i = 1; i < nargs; i++) { name = gctl_get_ascii(req, "arg%d", i); msize = g_get_mediasize(name); ssize = g_get_sectorsize(name); if (compsize < msize - ssize) { fprintf(stderr, "warning: %s: only %jd bytes from %jd bytes used.\n", name, (intmax_t)compsize, (intmax_t)(msize - ssize)); } md.md_no = i - 1; md.md_provsize = msize; if (!hardcode) bzero(md.md_provider, sizeof(md.md_provider)); else { if (strncmp(name, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) name += sizeof(_PATH_DEV) - 1; strlcpy(md.md_provider, name, sizeof(md.md_provider)); } stripe_metadata_encode(&md, sector); error = g_metadata_store(name, sector, sizeof(sector)); if (error != 0) { fprintf(stderr, "Can't store metadata on %s: %s.\n", name, strerror(error)); gctl_error(req, "Not fully done."); continue; } if (verbose) printf("Metadata value stored on %s.\n", name); } }
static void journal_label(struct gctl_req *req) { struct g_journal_metadata md; const char *data, *journal, *str; u_char sector[512]; intmax_t jsize, msize, ssize; int error, force, i, nargs, checksum, hardcode; nargs = gctl_get_int(req, "nargs"); str = NULL; /* gcc */ strlcpy(md.md_magic, G_JOURNAL_MAGIC, sizeof(md.md_magic)); md.md_version = G_JOURNAL_VERSION; md.md_id = arc4random(); md.md_joffset = 0; md.md_jid = 0; md.md_flags = GJ_FLAG_CLEAN; checksum = gctl_get_int(req, "checksum"); if (checksum) md.md_flags |= GJ_FLAG_CHECKSUM; force = gctl_get_int(req, "force"); hardcode = gctl_get_int(req, "hardcode"); if (nargs != 1 && nargs != 2) { gctl_error(req, "Invalid number of arguments."); return; } /* Verify the given providers. */ for (i = 0; i < nargs; i++) { str = gctl_get_ascii(req, "arg%d", i); if (g_get_mediasize(str) == 0) { gctl_error(req, "Invalid provider %s.", str); return; } } data = gctl_get_ascii(req, "arg0"); jsize = gctl_get_intmax(req, "jsize"); journal = NULL; switch (nargs) { case 1: if (!force && g_journal_fs_exists(data)) { gctl_error(req, "File system exists on %s and this " "operation would destroy it.\nUse -f if you " "really want to do it.", data); return; } journal = data; msize = g_get_mediasize(data); ssize = g_get_sectorsize(data); if (jsize == -1) { /* * No journal size specified. 1GB should be safe * default. */ jsize = 1073741824ULL; } else { if (jsize < 104857600) { gctl_error(req, "Journal too small."); return; } if ((jsize % ssize) != 0) { gctl_error(req, "Invalid journal size."); return; } } if (jsize + ssize >= msize) { gctl_error(req, "Provider too small for journalling. " "You can try smaller jsize (default is %jd).", jsize); return; } md.md_jstart = msize - ssize - jsize; md.md_jend = msize - ssize; break; case 2: if (!force && g_journal_fs_using_last_sector(data)) { gctl_error(req, "File system on %s is using the last " "sector and this operation is going to overwrite " "it. Use -f if you really want to do it.", data); return; } journal = gctl_get_ascii(req, "arg1"); if (jsize != -1) { gctl_error(req, "jsize argument is valid only for " "all-in-one configuration."); return; } msize = g_get_mediasize(journal); ssize = g_get_sectorsize(journal); md.md_jstart = 0; md.md_jend = msize - ssize; break; } if (g_get_sectorsize(data) != g_get_sectorsize(journal)) { gctl_error(req, "Not equal sector sizes."); return; } /* * Clear last sector first, to spoil all components if device exists. */ for (i = 0; i < nargs; i++) { str = gctl_get_ascii(req, "arg%d", i); error = g_metadata_clear(str, NULL); if (error != 0) { gctl_error(req, "Cannot clear metadata on %s: %s.", str, strerror(error)); return; } } /* * Ok, store metadata. */ for (i = 0; i < nargs; i++) { switch (i) { case 0: str = data; md.md_type = GJ_TYPE_DATA; if (nargs == 1) md.md_type |= GJ_TYPE_JOURNAL; break; case 1: str = journal; md.md_type = GJ_TYPE_JOURNAL; break; } md.md_provsize = g_get_mediasize(str); assert(md.md_provsize != 0); if (!hardcode) bzero(md.md_provider, sizeof(md.md_provider)); else { if (strncmp(str, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) str += sizeof(_PATH_DEV) - 1; strlcpy(md.md_provider, str, sizeof(md.md_provider)); } journal_metadata_encode(&md, sector); error = g_metadata_store(str, sector, sizeof(sector)); if (error != 0) { fprintf(stderr, "Cannot store metadata on %s: %s.\n", str, strerror(error)); gctl_error(req, "Not fully done."); continue; } if (verbose) printf("Metadata value stored on %s.\n", str); } }
static void mp_label(struct gctl_req *req) { struct g_multipath_metadata md; off_t disksize = 0, msize; uint8_t *sector, *rsector; char *ptr; uuid_t uuid; ssize_t secsize = 0, ssize; uint32_t status; const char *name, *name2, *mpname; int error, i, nargs, fd; nargs = gctl_get_int(req, "nargs"); if (nargs < 2) { gctl_error(req, "wrong number of arguments."); return; } /* * First, check each provider to make sure it's the same size. * This also gets us our size and sectorsize for the metadata. */ for (i = 1; i < nargs; i++) { name = gctl_get_ascii(req, "arg%d", i); msize = g_get_mediasize(name); ssize = g_get_sectorsize(name); if (msize == 0 || ssize == 0) { gctl_error(req, "cannot get information about %s: %s.", name, strerror(errno)); return; } if (i == 1) { secsize = ssize; disksize = msize; } else { if (secsize != ssize) { gctl_error(req, "%s sector size %ju different.", name, (intmax_t)ssize); return; } if (disksize != msize) { gctl_error(req, "%s media size %ju different.", name, (intmax_t)msize); return; } } } /* * Generate metadata. */ strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic)); md.md_version = G_MULTIPATH_VERSION; mpname = gctl_get_ascii(req, "arg0"); strlcpy(md.md_name, mpname, sizeof(md.md_name)); md.md_size = disksize; md.md_sectorsize = secsize; uuid_create(&uuid, &status); if (status != uuid_s_ok) { gctl_error(req, "cannot create a UUID."); return; } uuid_to_string(&uuid, &ptr, &status); if (status != uuid_s_ok) { gctl_error(req, "cannot stringify a UUID."); return; } strlcpy(md.md_uuid, ptr, sizeof (md.md_uuid)); md.md_active_active = gctl_get_int(req, "active_active"); free(ptr); /* * Allocate a sector to write as metadata. */ sector = malloc(secsize); if (sector == NULL) { gctl_error(req, "unable to allocate metadata buffer"); return; } memset(sector, 0, secsize); rsector = malloc(secsize); if (rsector == NULL) { free(sector); gctl_error(req, "unable to allocate metadata buffer"); return; } /* * encode the metadata */ multipath_metadata_encode(&md, sector); /* * Store metadata on the initial provider. */ name = gctl_get_ascii(req, "arg1"); error = g_metadata_store(name, sector, secsize); if (error != 0) { gctl_error(req, "cannot store metadata on %s: %s.", name, strerror(error)); return; } /* * Now touch the rest of the providers to hint retaste. */ for (i = 2; i < nargs; i++) { name2 = gctl_get_ascii(req, "arg%d", i); fd = g_open(name2, 1); if (fd < 0) { fprintf(stderr, "Unable to open %s: %s.\n", name2, strerror(errno)); continue; } if (pread(fd, rsector, secsize, disksize - secsize) != (ssize_t)secsize) { fprintf(stderr, "Unable to read metadata from %s: %s.\n", name2, strerror(errno)); g_close(fd); continue; } g_close(fd); if (memcmp(sector, rsector, secsize)) { fprintf(stderr, "No metadata found on %s." " It is not a path of %s.\n", name2, name); } } }