X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=daemon%2Flvm.c;h=7f31c84ed53965d49282f4818393ea07c2a56277;hp=1b888f240a381c560daa209b13dfef7eb1a8f8fb;hb=447b96e57cdf40ddc3b7669ba65dbea961748f71;hpb=73d6932ab2dd3f9120a1f4a532621c07cb174705 diff --git a/daemon/lvm.c b/daemon/lvm.c index 1b888f2..7f31c84 100644 --- a/daemon/lvm.c +++ b/daemon/lvm.c @@ -31,20 +31,141 @@ * of writing it hasn't progressed very far. */ -guestfs_lvm_int_pv_list * +static char ** +convert_lvm_output (char *out, char *prefix) +{ + char *p, *pend; + char **r = NULL; + int size = 0, alloc = 0; + int len; + char buf[256]; + char *str; + + p = out; + while (p) { + pend = strchr (p, '\n'); /* Get the next line of output. */ + if (pend) { + *pend = '\0'; + pend++; + } + + while (*p && isspace (*p)) /* Skip any leading whitespace. */ + p++; + + /* Sigh, skip trailing whitespace too. "pvs", I'm looking at you. */ + len = strlen (p)-1; + while (*p && isspace (p[len])) + p[len--] = '\0'; + + if (!*p) { /* Empty line? Skip it. */ + p = pend; + continue; + } + + /* Prefix? */ + if (prefix) { + snprintf (buf, sizeof buf, "%s%s", prefix, p); + str = buf; + } else + str = p; + + if (add_string (&r, &size, &alloc, str) == -1) { + free (out); + return NULL; + } + + p = pend; + } + + free (out); + + if (add_string (&r, &size, &alloc, NULL) == -1) + return NULL; + + sort_strings (r, size-1); + return r; +} + +char ** do_pvs (void) { + char *out, *err; + int r; + + r = command (&out, &err, + "/sbin/lvm", "pvs", "-o", "pv_name", "--noheadings", NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (out); + free (err); + return NULL; + } + + free (err); + + return convert_lvm_output (out, NULL); +} + +char ** +do_vgs (void) +{ + char *out, *err; + int r; + + r = command (&out, &err, + "/sbin/lvm", "vgs", "-o", "vg_name", "--noheadings", NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (out); + free (err); + return NULL; + } + + free (err); + + return convert_lvm_output (out, NULL); +} + +char ** +do_lvs (void) +{ + char *out, *err; + int r; + + r = command (&out, &err, + "/sbin/lvm", "lvs", + "-o", "vg_name,lv_name", "--noheadings", + "--separator", "/", NULL); + if (r == -1) { + reply_with_error ("%s", err); + free (out); + free (err); + return NULL; + } + + free (err); + + return convert_lvm_output (out, "/dev/"); +} + +/* These were so complex to implement that I ended up auto-generating + * the code. That code is in stubs.c, and it is generated as usual + * by generator.ml. + */ +guestfs_lvm_int_pv_list * +do_pvs_full (void) +{ return parse_command_line_pvs (); } guestfs_lvm_int_vg_list * -do_vgs (void) +do_vgs_full (void) { return parse_command_line_vgs (); } guestfs_lvm_int_lv_list * -do_lvs (void) +do_lvs_full (void) { return parse_command_line_lvs (); }