Re: [Libguestfs] [PATCH] New API: part_get_part_type for showing partition type
On Tue, Mar 17, 2015 at 02:45:46AM -0400, Chen Hanxiao wrote: This patch will add support for getting partition type of a partiton numbered device. Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com --- daemon/parted.c | 112 +++ generator/actions.ml | 18 + src/MAX_PROC_NR | 2 +- 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/daemon/parted.c b/daemon/parted.c index a7bcb99..0ae6e5c 100644 --- a/daemon/parted.c +++ b/daemon/parted.c @@ -33,6 +33,10 @@ GUESTFSD_EXT_CMD(str_parted, parted); GUESTFSD_EXT_CMD(str_sfdisk, sfdisk); GUESTFSD_EXT_CMD(str_sgdisk, sgdisk); +#ifndef PARTED_NO_M +# define PARTED_NO_M 0 +#endif What does this bit do? /* Notes: * * Parted 1.9 sends error messages to stdout, hence use of the @@ -1022,3 +1026,111 @@ do_part_get_name (const char *device, int partnum) reply_with_error (cannot get the partition name from '%s' layouts, parttype); return NULL; } + +char * +do_part_get_part_type (const char *device, int partnum) +{ + CLEANUP_FREE char *parttype; + char *part_type; + + if (partnum = 0) { +reply_with_error (partition number must be = 1); +return NULL; + } + + parttype = do_part_get_parttype (device); + if (parttype == NULL) +return NULL; + + if (STREQ (parttype, gpt)) { +part_type = strdup(primary); +if (part_type == NULL) { + reply_with_error (strdup failed); + return NULL; +} +return part_type; + } + + /* machine parseable output by 'parted -m' did not provide + * partition type info. + * Use traditional style. + */ + CLEANUP_FREE char *out = print_partition_table (device, PARTED_NO_M); + if (!out) +return NULL; + + CLEANUP_FREE_STRING_LIST char **lines = split_lines (out); + + if (!lines) +return NULL; + + size_t start = 0, end = 0, row; + + for (row = 0; lines[row] != NULL; ++row) +if (STRPREFIX (lines[row], Number)) { + start = row + 1; + break; +} + + if (start == 0) { +reply_with_error (parted output has no \Number\ line); +return NULL; + } + + for (row = start; lines[row] != NULL; ++row) +if (STREQ (lines[row], )) { + end = row; + break; +} + + if (end == 0) { +reply_with_error (parted output has no blank after end of table); +return NULL; + } + + /* Now parse the lines. */ + size_t i; + int64_t temp_int64; + int part_num; + char temp_type[16]; + for (i = 0, row = start; row end; ++i, ++row) { +if (sscanf (lines[row], %d% SCNi64 B% SCNi64 B% SCNi64 B %s, +part_num, +temp_int64, +temp_int64, +temp_int64, +temp_type) != 5) { We're hoping here that the output of 'parted' never changes and overflows the 16 byte buffer. Instead of hoping, you can guarantee that by replacing %s with %15s + reply_with_error (could not parse row from output of parted print command: %s, lines[row]); + return NULL; +} + +if (part_num != partnum) +continue; + +if (STRPREFIX (temp_type, primary)) { + part_type = strdup(primary); + if (part_type == NULL) + goto error; +} else if (STRPREFIX (temp_type, logical)) { + part_type = strdup(logical); + if (part_type == NULL) + goto error; +} else if (STRPREFIX (temp_type, extended)) { + part_type = strdup(extended); + if (part_type == NULL) + goto error; +} else +goto error; + +return part_type; + } + + if (row == end) { +reply_with_error (could not find partnum: %d, partnum); +return NULL; + } + + error: +reply_with_error (strdup failed); +return NULL; +} diff --git a/generator/actions.ml b/generator/actions.ml index fb971d3..72418b0 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -12522,6 +12522,24 @@ This will Enable extended inode refs. }; longdesc = \ This enable skinny metadata extent refs. }; + { defaults with +name = part_get_part_type; +style = RString partitiontype, [Device device; Int partnum], []; +proc_nr = Some 453; +tests = [ + InitEmpty, Always, TestResultString ( +[[part_init; /dev/sda; mbr]; + [part_add; /dev/sda; p; 64; 204799]; + [part_add; /dev/sda; e; 204800; 614400]; + [part_add; /dev/sda; l; 204864; 205988]; + [part_get_part_type; /dev/sda; 5]], logical), [] +]; + +shortdesc = get the partition type; +longdesc = \ +This could get the partition type, such as primary, logical, +on partition numbered Cpartnum on device Cdevice. }; + ] (* Non-API meta-commands available only in guestfish. diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index 8670c73..534b992 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1
Re: [Libguestfs] [PATCH v2] customize: add --truncate-recursive option
Thanks - ACKed and pushed. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-p2v converts physical machines to virtual machines. Boot with a live CD or over the network (PXE) and turn machines into KVM guests. http://libguestfs.org/virt-v2v ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH v2] btrfs-qgroup-show: add check for --raw
ACKed and (will) push. Thanks, Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH v2] New API: btrfs-image
On Tue, Mar 17, 2015 at 02:53:35AM -0400, Chen Hanxiao wrote: + /* btrfs-progs will valid numtheads and choose the right one for us */ + if ((optargs_bitmask GUESTFS_BTRFS_IMAGE_NUMTHREADS_BITMASK) + numthreads) { +snprintf (numthreads_s, sizeof numthreads_s, %d, numthreads); +ADD_ARG (argv, i, -t); +ADD_ARG (argv, i, numthreads_s); + } Can you get rid of this, as I think it's an implementation detail. We don't need to expose the -t/threads to API users. The patch is fine otherwise. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/ ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH] fuse: resolve absolute links to relative ones
On Wed, Mar 18, 2015 at 02:21:31PM +0100, Maros Zatko wrote: First it strips /sysroot and then finds common prefix aligned on slashes. Next it produces ../ for each slash found in common prefix and concatenates them with the rest of resolved link. Fixes RHBZ#604041 --- src/fuse.c | 33 - 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/fuse.c b/src/fuse.c index 3fdb1d4..6c7eee1 100644 --- a/src/fuse.c +++ b/src/fuse.c @@ -386,7 +386,38 @@ mount_local_readlink (const char *path, char *buf, size_t size) if (len size - 1) len = size - 1; - memcpy (buf, r, len); + buf[0] = '\0'; + size_t offset = 0; + if (STRPREFIX (r, /sysroot)) { +offset = strlen (/sysroot) + 1; +size_t i; +for (i = 0; (i strlen (r+offset)) (path[i] == r[i+offset-1]); i++); +/* Now i contains index where paths starts to differ + * (n.b. needs to be aligned on last slash). */ + +for (; path[i] != '/'; --i); +/* i is now aligned */ + +/* Count slashes in original path, so we can generate + * right amount of ../ */ +size_t j; int cnt = 0; +for (j = i+1; j strlen (r+offset); j++) { + if (path[j] == '/') cnt++; +} + +/* For each slash create ../ in path */ +for (int z = 0; z cnt; z++) { + strcat (buf, ../); +} + +/* In addition to /sysroot ne need to remove common path + * aligned on slashes */ +offset += i; + } + + /* There might already be something in buf (such as ../) + * so let's concatenate the rest of path */ + strncat (buf, r + offset, len - offset + 1); buf[len] = '\0'; This makes my head hurt. Perhaps some diagrams or examples of how this is supposed to work? Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/ ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH v3] fish: add journal-view command
On Thu, Mar 05, 2015 at 04:51:00PM +0100, Maros Zatko wrote: Lets user view journald log from VM in a similar format as journalctl uses. Makes virt-log use the same code as guestfish for journal-view. Fixes RFE: journal reader in guestfish (RHBZ#988100) I think this patch could be in two parts, one where you move the journal_view() code from cat/log.c into fish/journal.c, and a second part where you add the extra command. More comments below. cat/Makefile.am | 1 + cat/log.c| 113 +--- fish/Makefile.am | 1 + fish/fish.h | 3 + fish/journal.c | 178 +++ generator/actions.ml | 9 +++ 6 files changed, 195 insertions(+), 110 deletions(-) create mode 100644 fish/journal.c diff --git a/cat/Makefile.am b/cat/Makefile.am index d0db6fa..d472100 100644 --- a/cat/Makefile.am +++ b/cat/Makefile.am @@ -38,6 +38,7 @@ bin_PROGRAMS = virt-cat virt-filesystems virt-log virt-ls SHARED_SOURCE_FILES = \ ../fish/domain.c \ ../fish/inspect.c \ + ../fish/journal.c \ ../fish/keys.c \ ../fish/options.h \ ../fish/options.c \ diff --git a/cat/log.c b/cat/log.c index 616baed..c72946b 100644 --- a/cat/log.c +++ b/cat/log.c @@ -36,6 +36,7 @@ #include guestfs.h #include options.h +#include fish.h /* Currently open libguestfs handle. */ guestfs_h *g; @@ -273,128 +274,20 @@ do_log (void) return 0; } -/* Find the value of the named field from the list of attributes. If - * not found, returns NULL (not an error). If found, returns a - * pointer to the field, and the length of the field. NOTE: The field - * is NOT \0-terminated, so you have to print it using %.*s. - * - * There may be multiple fields with the same name. In this case, the - * function returns the first entry. - */ -static const char * -get_journal_field (const struct guestfs_xattr_list *xattrs, const char *name, - size_t *len_rtn) -{ - uint32_t i; - - for (i = 0; i xattrs-len; ++i) { -if (STREQ (name, xattrs-val[i].attrname)) { - *len_rtn = xattrs-val[i].attrval_len; - return xattrs-val[i].attrval; -} - } - - return NULL; /* not found */ -} - -static const char *const log_level_table[] = { - [LOG_EMERG] = emerg, - [LOG_ALERT] = alert, - [LOG_CRIT] = crit, - [LOG_ERR] = err, - [LOG_WARNING] = warning, - [LOG_NOTICE] = notice, - [LOG_INFO] = info, - [LOG_DEBUG] = debug -}; - static int do_log_journal (void) { int r; - unsigned errors = 0; - if (guestfs_journal_open (g, JOURNAL_DIR) == -1) return -1; - while ((r = guestfs_journal_next (g)) 0) { -CLEANUP_FREE_XATTR_LIST struct guestfs_xattr_list *xattrs = NULL; -const char *priority_str, *identifier, *comm, *pid, *message; -size_t priority_len, identifier_len, comm_len, pid_len, message_len; -int priority = LOG_INFO; -int64_t ts; - -/* The question is what fields to display. We should probably - * make this configurable, but for now use the short format from - * journalctl. (XXX) - */ - -xattrs = guestfs_journal_get (g); -if (xattrs == NULL) - return -1; - -ts = guestfs_journal_get_realtime_usec (g); /* error checked below */ - -priority_str = get_journal_field (xattrs, PRIORITY, priority_len); -//hostname = get_journal_field (xattrs, _HOSTNAME, hostname_len); -identifier = get_journal_field (xattrs, SYSLOG_IDENTIFIER, -identifier_len); -comm = get_journal_field (xattrs, _COMM, comm_len); -pid = get_journal_field (xattrs, _PID, pid_len); -message = get_journal_field (xattrs, MESSAGE, message_len); - -/* Timestamp. */ -if (ts = 0) { - char buf[64]; - time_t t = ts / 100; - struct tm tm; - - if (strftime (buf, sizeof buf, %b %d %H:%M:%S, -localtime_r (t, tm)) = 0) { -fprintf (stderr, _(%s: could not format journal entry timestamp\n), - guestfs_int_program_name); -errors++; -continue; - } - fputs (buf, stdout); -} - -/* Hostname. */ -/* We don't print this because it is assumed each line from the - * guest will have the same hostname. (XXX) - */ -//if (hostname) -// printf ( %.*s, (int) hostname_len, hostname); - -/* Identifier. */ -if (identifier) - printf ( %.*s, (int) identifier_len, identifier); -else if (comm) - printf ( %.*s, (int) comm_len, comm); - -/* PID */ -if (pid) - printf ([%.*s], (int) pid_len, pid); - -/* Log level. */ -if (priority_str *priority_str = '0' *priority_str = '7') - priority = *priority_str - '0'; - -printf ( %s:, log_level_table[priority]); - -/* Message. */ -if (message) -
Re: [Libguestfs] [PATCH] guestfs.pod: don't encourage 'make syntax-check'
On Fri, Mar 13, 2015 at 01:32:59AM -0400, Chen Hanxiao wrote: Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com --- src/guestfs.pod | 4 1 file changed, 4 deletions(-) diff --git a/src/guestfs.pod b/src/guestfs.pod index 377db21..70400a1 100644 --- a/src/guestfs.pod +++ b/src/guestfs.pod @@ -4158,10 +4158,6 @@ Runs the regular test suite. This is implemented using the regular automake CTESTS target. See the automake documentation for details. -=item Cmake syntax-check -j1 -k - -Checks for various syntax and style problems in the code. - =item Cmake check-valgrind Runs a subset of the test suite under valgrind. -- 2.1.0 Sorry for the delay. ACKed and pushed. Thanks, Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH] builder: handle empty lines in indexes before first section (RHBZ#1201526)
ACK. I'll push this shortly. Thanks, Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH] inspection: add support for systemd .mount files
On Mon, Mar 16, 2015 at 07:09:51PM +0100, Maros Zatko wrote: Fixes RHBZ#1113153. --- src/inspect-fs-unix.c | 240 ++ 1 file changed, 240 insertions(+) diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c index 2abbf24..6dfc299 100644 --- a/src/inspect-fs-unix.c +++ b/src/inspect-fs-unix.c @@ -96,6 +96,9 @@ static char *resolve_fstab_device (guestfs_h *g, const char *spec, Hash_table *md_map, enum inspect_os_type os_type); static int inspect_with_augeas (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *)); +static int inspect_with_augeas2 (guestfs_h *g, struct inspect_fs *fs, const char **configfiles, int (*f) (guestfs_h *, struct inspect_fs *, const char *)); I think there is a case for splitting out the commit which adds this new function. Also, do we need a new function? I don't see why it's needed at all - just modify the old inspect_with_augeas so it passes the extra parameter always, and update the call sites [in a separate commit]. +static int check_systemd_mounts (guestfs_h *g, struct inspect_fs *fs); +static int check_systemd_mnt (guestfs_h *g, struct inspect_fs *fs, const char *path); You don't need to prototype check_systemd_mnt at all - just remove that line as it's confusing for people reading the code. /* Hash structure for uuid-path lookups */ typedef struct md_uuid { @@ -582,6 +585,9 @@ guestfs_int_check_linux_root (guestfs_h *g, struct inspect_fs *fs) if (check_hostname_unix (g, fs) == -1) return -1; + if (check_systemd_mounts (g, fs) == -1) +return -1; + return 0; } @@ -981,6 +987,180 @@ check_hostname_freebsd (guestfs_h *g, struct inspect_fs *fs) } static int +check_systemd_mnt (guestfs_h *g, struct inspect_fs *fs, const char *fname) +{ + CLEANUP_FREE_STRING_LIST char **entries = NULL; + char **entry; + char augpath[256]; + CLEANUP_HASH_FREE Hash_table *md_map = NULL; + bool is_bsd = (fs-type == OS_TYPE_FREEBSD || + fs-type == OS_TYPE_NETBSD || + fs-type == OS_TYPE_OPENBSD); + + /* Generate a map of MD device paths listed in /etc/mdadm.conf to MD device + * paths in the guestfs appliance */ + if (map_md_devices (g, md_map) == -1) { +printf (map_md_dev fail\n); This printf shouldn't be here. +return -1; + } + + char expr[512]; + snprintf (expr, sizeof expr, /files%s, fname); Yikes. Don't use fixed size buffers, especially where (as seems to be the case here) the path comes from user input. Use: CLEANUP_FREE char *expr = NULL; ... expr = safe_asprintf (g, /files%s, fname); + entries = guestfs_aug_match (g, expr); + if (entries == NULL) { +return 0; + } + + for (entry = entries; *entry != NULL; entry++) { +CLEANUP_FREE char *spec = NULL; +CLEANUP_FREE char *mp = NULL; +CLEANUP_FREE char *mountable = NULL; +CLEANUP_FREE char *vfstype = NULL; + +snprintf (augpath, sizeof augpath, %s/Mount/What/value, *entry); +spec = guestfs_aug_get (g, augpath); +if (spec == NULL) + return -1; + +/* Ignore /dev/fd (floppy disks) (RHBZ#642929) and CD-ROM drives. + * + * /dev/iso9660/FREEBSD_INSTALL can be found in FreeBSDs installation + * discs. + */ +if ((STRPREFIX (spec, /dev/fd) c_isdigit (spec[7])) || +STREQ (spec, /dev/floppy) || +STREQ (spec, /dev/cdrom) || +STRPREFIX (spec, /dev/iso9660/)) + continue; [etc] There's a lot of common code with check_fstab here. It's not completely identical because the augeas queries are slightly different, but you can parameterize those easily enough. A nice thing would be a separate commit which first moves the common code out from check_fstab into its own function. +static int +check_systemd_mounts (guestfs_h *g, struct inspect_fs *fs) +{ + const char *dirs[] = {/etc/systemd/, /lib/systemd/, +/usr/lib/systemd/, NULL}; + const char **dir; + for (dir = dirs; *dir != NULL; dir++) { +CLEANUP_FREE_STRING_LIST char **entries = NULL; +char **entry; + +entries = guestfs_find (g, *dir); Error check? If the command fails it will immediately segfault in the next line, which is something that inspection code cannot be doing -- it's a DoS attack route. +size_t cnt = guestfs_int_count_strings (entries); + +CLEANUP_FREE_STRING_LIST char **filenames = + safe_malloc (g, (cnt + 1) * sizeof (char *)); + +size_t idx = 0; +for (entry = entries; *entry != NULL; entry++) { + if (STRSUFFIX (*entry, .mount)) { +size_t entry_len = strlen(*dir) + strlen(*entry) + 1; +filenames[idx] = safe_malloc (g, entry_len); +snprintf (filenames[idx], entry_len, %s%s, *dir, *entry); +++idx; + } +} +filenames[idx] = NULL; +
Re: [Libguestfs] [PATCH] virt-ls: support drive letters on Windows
On Tue, Mar 17, 2015 at 03:33:09PM +0100, Maros Zatko wrote: --- cat/ls.c | 31 ++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/cat/ls.c b/cat/ls.c index 9161fb6..151c11d 100644 --- a/cat/ls.c +++ b/cat/ls.c @@ -37,6 +37,7 @@ #include options.h #include visit.h +#include windows.h /* Currently open libguestfs handle. */ guestfs_h *g; @@ -76,6 +77,8 @@ static void output_int64_uid (int64_t); static void output_string (const char *); static void output_string_link (const char *); +static char *from_maybe_windows_path (const char *); + static void __attribute__((noreturn)) usage (int status) { @@ -374,7 +377,7 @@ main (int argc, char *argv[]) unsigned errors = 0; while (optind argc) { -const char *dir = argv[optind]; +const char *dir = from_maybe_windows_path(argv[optind]); switch (mode) { case 0: /* no -l or -R option */ @@ -401,6 +404,7 @@ main (int argc, char *argv[]) abort (); /* can't happen */ } +free (dir); Use CLEANUP_FREE instead? optind++; } @@ -409,6 +413,31 @@ main (int argc, char *argv[]) exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } +static char * +from_maybe_windows_path (const char *dir) +{ + CLEANUP_FREE_STRING_LIST char **roots = NULL; + char *path = NULL; + char *root; + + roots = guestfs_inspect_get_roots (g); + assert (roots); + assert (roots[0] != NULL); + assert (roots[1] == NULL); + root = roots[0]; + + if (is_windows (g, root)) { +path = windows_path (g, root, dir, 1 /* readonly */ ); +if (path == NULL) { + guestfs_close (g); + exit (EXIT_FAILURE); +} +return path; + } + + return safe_strdup (g, dir); +} Hmmm. This isn't very similar to what cat/cat.c does. In cat/cat.c we do the inspection once only (inspection is expensive), and then we call windows_path conditionally based on that result. See: https://github.com/libguestfs/libguestfs/blob/master/cat/cat.c#L283-L301 Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/ ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH v3] virt-copy, virt-tar: show help for -h
On Fri, Feb 06, 2015 at 02:11:13PM +0100, Maros Zatko wrote: --- fish/virt-copy-in | 9 + fish/virt-copy-out | 9 + fish/virt-tar-in | 9 + fish/virt-tar-out | 9 + 4 files changed, 36 insertions(+) diff --git a/fish/virt-copy-in b/fish/virt-copy-in index 76ff57f..850f382 100755 --- a/fish/virt-copy-in +++ b/fish/virt-copy-in @@ -16,4 +16,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +for arg in $@; do + case $arg in +-h) This needs to be --help. I don't think anyone uses -h for help outside DOS programs. + man $(basename $0) + exit There are a few problems here: (1) You lose the exit code from 'man'. If you write the following instead: exec man $(basename $0) then the script will exit with the same exit code as the man process. (2) Quoting, maybe. Likely this is better: exec man $(basename $0) Anyway, I made these changes and pushed it. Thanks, Rich. + ;; + esac +done + exec guestfish --rw -i copy-in $@ diff --git a/fish/virt-copy-out b/fish/virt-copy-out index 20475ef..953c594 100755 --- a/fish/virt-copy-out +++ b/fish/virt-copy-out @@ -16,4 +16,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +for arg in $@; do + case $arg in +-h) + man $(basename $0) + exit + ;; + esac +done + exec guestfish --ro -i copy-out $@ diff --git a/fish/virt-tar-in b/fish/virt-tar-in index 1501b38..6662858 100755 --- a/fish/virt-tar-in +++ b/fish/virt-tar-in @@ -16,4 +16,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +for arg in $@; do + case $arg in +-h) + man $(basename $0) + exit + ;; + esac +done + exec guestfish --rw -i tar-in $@ diff --git a/fish/virt-tar-out b/fish/virt-tar-out index 4d30de4..19a1ed6 100755 --- a/fish/virt-tar-out +++ b/fish/virt-tar-out @@ -16,4 +16,13 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +for arg in $@; do + case $arg in +-h) + man $(basename $0) + exit + ;; + esac +done + exec guestfish --ro -i tar-out $@ -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-builder quickly builds VMs from scratch http://libguestfs.org/virt-builder.1.html ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v4] [RFE] virt-builder should support download resume
This adds support for resuming downloads in virt-builder. Partially downloaded image is not deleted on exit anymore. There is a check for partially downloaded image in cache directory based on its name. When found, download_to crafts appropriate options to continue its download. Fixes RHBZ#1198344 Ammended for forgotten unlink_on_exit and fixed call with optional aguments. Maros Zatko (1): builder: support for download resume builder/downloader.ml | 31 +-- 1 file changed, 25 insertions(+), 6 deletions(-) -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v4] builder: support for download resume
Partially downloaded image is not deleted on exit anymore. There is a check for partially downloaded image in cache directory based on its name. When found, download_to crafts appropriate options to continue its download. --- builder/downloader.ml | 31 +-- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/builder/downloader.ml b/builder/downloader.ml index 8a23bdc..feda745 100644 --- a/builder/downloader.ml +++ b/builder/downloader.ml @@ -65,11 +65,11 @@ let rec download ~prog t ?template ?progress_bar ?(proxy = SystemProxy) uri = * If not, download it. *) if not (Sys.file_exists filename) then -download_to ~prog t ?progress_bar ~proxy uri filename; +download_to ~prog t ?progress_bar ~continue:true ~proxy uri filename; (filename, false) -and download_to ~prog t ?(progress_bar = false) ~proxy uri filename = +and download_to ~prog t ?(progress_bar = false) ?(continue = false) ~proxy uri filename = let parseduri = try URI.parse_uri uri with Invalid_argument URI.parse_uri - @@ -82,9 +82,10 @@ and download_to ~prog t ?(progress_bar = false) ~proxy uri filename = * atomically rename it to the final filename. *) let filename_new = filename ^ . ^ string_random8 () in - unlink_on_exit filename_new; + if not continue then +unlink_on_exit filename_new; - (match parseduri.URI.protocol with + let filename_new = (match parseduri.URI.protocol with | file - let path = parseduri.URI.path in let cmd = sprintf cp%s %s %s @@ -93,6 +94,7 @@ and download_to ~prog t ?(progress_bar = false) ~proxy uri filename = let r = Sys.command cmd in if r 0 then error (f_cp (download) command failed copying '%s') path; +filename_new | _ as protocol - (* Any other protocol. *) let outenv = proxy_envvar protocol proxy in (* Get the status code first to ensure the file exists. *) @@ -115,17 +117,34 @@ and download_to ~prog t ?(progress_bar = false) ~proxy uri filename = if bad_status_code status_code then error (f_failed to download %s: HTTP status code %s) uri status_code; +let compare_basenames a b = + (Filename.basename a) = (try Filename.chop_extension b with _ - b) +in + +let files = Array.to_list (Sys.readdir (Filename.dirname filename)) in +let files = + if continue then +List.filter (compare_basenames filename) files + else +[] in + +let filename_new, continue_download = match files with + | [] - filename_new, + | fil::_ - (Filename.dirname filename_new) // fil, -C - in + (* Now download the file. *) -let cmd = sprintf %s%s%s -g -o %s %s +let cmd = sprintf %s%s%s%s -g -o %s %s outenv t.curl (if t.verbose then else if progress_bar then -# else -s -S) + continue_download (quote filename_new) (quote uri) in if t.verbose then printf %s\n%! cmd; let r = Sys.command cmd in if r 0 then error (f_curl (download) command failed downloading '%s') uri; - ); +filename_new + ) in (* Rename the file if the download was successful. *) rename filename_new filename -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] Inspection of disk snapshots
Greetings, I have the following typical scenario: given one or more qcow2 base images I clone them with COW and start the VMs. At a certain point I'd like to inspect them in order to see their evolution compared to the known base images. To do so I was thinking about taking a disk snapshot of each VM and inspect its content through libguestfs (using it's Python bindings). Obviously I need the base image in order for libguestfs to correctly guess the OS, the FS structure etc.. Problem is that that point when I inspect the disk I get the whole disk state including the base image content (30K+ files and directories). This is not an issue but it's a very heavy operation considering that some of the snapshots are few megabytes while the base images are several gigabytes. Is there a way to programmatically instruct libguestfs to limit the inspection to the sole snapshot? Would it work as well with other disk format (vmdk linked clones for example)? For better comprehension I'll show the sequence I'm doing (I might do it wrong of course): virsh -c qemu:///system snapshot-create --disk-only domain-ID I get the snapshot location from its XML description and then: qemu-img convert -f qcow2 -O qcow2 base_image.qcow2 snapshot.qcow2 At that point I mount it through libguestfs and inspect its content. Thank you. ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH v3] [RFE] virt-builder should support download resume
Ah, disregard this please. I should have read emails first :) ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH 1/2] mllib: allow external_command to return [] on nonzero return value
On Wed, Mar 18, 2015 at 05:20:06PM +0100, Maros Zatko wrote: This is useful for probing probing for cache files such as: external_command ?ignore_error:(Some true) ~prog ls .cache/something.* will return command output (matched files) on its success or empty list whenits exit code is other than 0 (there are no such files). I would write this as: let files = Sys.readdir .cache inm let files = Array.to_list files in let files = List.filter (fun s - string_prefix s something.) in (* or if you just want to check existence of any something.* file: let file_exists = List.exists (fun s - string_prefix s something.) in *) Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v3] builder: support for download resume
Partially downloaded file is not deleted on exit anymore. There is a check for partially downloaded image in cache directory based on its name. When found, download_to crafts appropriate options to continue its download. --- builder/downloader.ml | 31 +-- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/builder/downloader.ml b/builder/downloader.ml index 8a23bdc..36f89ae 100644 --- a/builder/downloader.ml +++ b/builder/downloader.ml @@ -65,11 +65,11 @@ let rec download ~prog t ?template ?progress_bar ?(proxy = SystemProxy) uri = * If not, download it. *) if not (Sys.file_exists filename) then -download_to ~prog t ?progress_bar ~proxy uri filename; +download_to ~prog t ?progress_bar ?continue:(Some true) ~proxy uri filename; (filename, false) -and download_to ~prog t ?(progress_bar = false) ~proxy uri filename = +and download_to ~prog t ?(progress_bar = false) ?(continue = false) ~proxy uri filename = let parseduri = try URI.parse_uri uri with Invalid_argument URI.parse_uri - @@ -82,9 +82,10 @@ and download_to ~prog t ?(progress_bar = false) ~proxy uri filename = * atomically rename it to the final filename. *) let filename_new = filename ^ . ^ string_random8 () in - unlink_on_exit filename_new; + if not continue then +unlink_on_exit filename_new; - (match parseduri.URI.protocol with + let filename_new = (match parseduri.URI.protocol with | file - let path = parseduri.URI.path in let cmd = sprintf cp%s %s %s @@ -93,6 +94,7 @@ and download_to ~prog t ?(progress_bar = false) ~proxy uri filename = let r = Sys.command cmd in if r 0 then error (f_cp (download) command failed copying '%s') path; +filename_new | _ as protocol - (* Any other protocol. *) let outenv = proxy_envvar protocol proxy in (* Get the status code first to ensure the file exists. *) @@ -115,17 +117,34 @@ and download_to ~prog t ?(progress_bar = false) ~proxy uri filename = if bad_status_code status_code then error (f_failed to download %s: HTTP status code %s) uri status_code; +let compare_basenames a b = + (Filename.basename a) = (try Filename.chop_extension b with _ - b) +in + +let files = Array.to_list (Sys.readdir (Filename.dirname filename)) in +let files = + if continue then +List.filter (compare_basenames filename) files + else +[] in + +let filename_new, continue_download = match files with + | [] - filename_new, + | fil::_ - (Filename.dirname filename_new) // fil, -C - in + (* Now download the file. *) -let cmd = sprintf %s%s%s -g -o %s %s +let cmd = sprintf %s%s%s%s -g -o %s %s outenv t.curl (if t.verbose then else if progress_bar then -# else -s -S) + continue_download (quote filename_new) (quote uri) in if t.verbose then printf %s\n%! cmd; let r = Sys.command cmd in if r 0 then error (f_curl (download) command failed downloading '%s') uri; - ); +filename_new + ) in (* Rename the file if the download was successful. *) rename filename_new filename -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v3] [RFE] virt-builder should support download resume
This adds support for resuming downloads in virt-builder. Partially downloaded file is not deleted on exit anymore. There is a check for partially downloaded image in cache directory based on its name. When found, download_to crafts appropriate options to continue its download. Fixes RHBZ#1198344 Ammended for forgotten unlink_on_exit. Maros Zatko (1): builder: support for download resume builder/downloader.ml | 31 +-- 1 file changed, 25 insertions(+), 6 deletions(-) -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH] New API: part_get_part_type for showing partition type
-Original Message- From: Richard W.M. Jones [mailto:rjo...@redhat.com] Sent: Monday, March 23, 2015 9:29 PM To: Chen, Hanxiao/陈 晗霄 Cc: libguestfs@redhat.com Subject: Re: [Libguestfs] [PATCH] New API: part_get_part_type for showing partition type On Tue, Mar 17, 2015 at 02:45:46AM -0400, Chen Hanxiao wrote: This patch will add support for getting partition type of a partiton numbered device. Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com --- daemon/parted.c | 112 +++ generator/actions.ml | 18 + src/MAX_PROC_NR | 2 +- 3 files changed, 131 insertions(+), 1 deletion(-) diff --git a/daemon/parted.c b/daemon/parted.c index a7bcb99..0ae6e5c 100644 --- a/daemon/parted.c +++ b/daemon/parted.c @@ -33,6 +33,10 @@ GUESTFSD_EXT_CMD(str_parted, parted); GUESTFSD_EXT_CMD(str_sfdisk, sfdisk); GUESTFSD_EXT_CMD(str_sgdisk, sgdisk); +#ifndef PARTED_NO_M +# define PARTED_NO_M 0 +#endif What does this bit do? I want to use print_partition_table(xxx, 0) but do not want to pass a raw '0'. Maybe the name is not so clear. I'll rename it to PARTED_NOT_USE_M in the next version. /* Notes: * * Parted 1.9 sends error messages to stdout, hence use of the @@ -1022,3 +1026,111 @@ do_part_get_name (const char *device, int partnum) reply_with_error (cannot get the partition name from '%s' layouts, parttype); return NULL; } + +char * +do_part_get_part_type (const char *device, int partnum) +{ + CLEANUP_FREE char *parttype; + char *part_type; + + if (partnum = 0) { +reply_with_error (partition number must be = 1); +return NULL; + } + + parttype = do_part_get_parttype (device); + if (parttype == NULL) +return NULL; + + if (STREQ (parttype, gpt)) { +part_type = strdup(primary); +if (part_type == NULL) { + reply_with_error (strdup failed); + return NULL; +} +return part_type; + } + + /* machine parseable output by 'parted -m' did not provide + * partition type info. + * Use traditional style. + */ + CLEANUP_FREE char *out = print_partition_table (device, PARTED_NO_M); + if (!out) +return NULL; + + CLEANUP_FREE_STRING_LIST char **lines = split_lines (out); + + if (!lines) +return NULL; + + size_t start = 0, end = 0, row; + + for (row = 0; lines[row] != NULL; ++row) +if (STRPREFIX (lines[row], Number)) { + start = row + 1; + break; +} + + if (start == 0) { +reply_with_error (parted output has no \Number\ line); +return NULL; + } + + for (row = start; lines[row] != NULL; ++row) +if (STREQ (lines[row], )) { + end = row; + break; +} + + if (end == 0) { +reply_with_error (parted output has no blank after end of table); +return NULL; + } + + /* Now parse the lines. */ + size_t i; + int64_t temp_int64; + int part_num; + char temp_type[16]; + for (i = 0, row = start; row end; ++i, ++row) { +if (sscanf (lines[row], %d% SCNi64 B% SCNi64 B% SCNi64 B %s, +part_num, +temp_int64, +temp_int64, +temp_int64, +temp_type) != 5) { We're hoping here that the output of 'parted' never changes and overflows the 16 byte buffer. Instead of hoping, you can guarantee that by replacing %s with %15s Will fix. Regards, - Chen + reply_with_error (could not parse row from output of parted print command: %s, lines[row]); + return NULL; +} + +if (part_num != partnum) +continue; + +if (STRPREFIX (temp_type, primary)) { + part_type = strdup(primary); + if (part_type == NULL) + goto error; +} else if (STRPREFIX (temp_type, logical)) { + part_type = strdup(logical); + if (part_type == NULL) + goto error; +} else if (STRPREFIX (temp_type, extended)) { + part_type = strdup(extended); + if (part_type == NULL) + goto error; +} else +goto error; + +return part_type; + } + + if (row == end) { +reply_with_error (could not find partnum: %d, partnum); +return NULL; + } + + error: +reply_with_error (strdup failed); +return NULL; +} diff --git a/generator/actions.ml b/generator/actions.ml index fb971d3..72418b0 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -12522,6 +12522,24 @@ This will Enable extended inode refs. }; longdesc = \ This enable skinny metadata extent refs. }; + { defaults with +name = part_get_part_type; +style = RString partitiontype, [Device device; Int partnum], []; +proc_nr = Some 453; +tests = [ + InitEmpty, Always, TestResultString ( +
[Libguestfs] [PATCH v2] RFE: support Windows drive letters in virt-ls
It is modelled after virt-cat. Fixes RHBZ#845234 Ammended so it doesn't do inspection for every dir to list. Maros Zatko (1): virt-ls: support drive letters on Windows cat/ls.c | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v2] virt-ls: support drive letters on Windows
--- cat/ls.c | 32 +++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/cat/ls.c b/cat/ls.c index 9161fb6..b7a99b2 100644 --- a/cat/ls.c +++ b/cat/ls.c @@ -37,6 +37,7 @@ #include options.h #include visit.h +#include windows.h /* Currently open libguestfs handle. */ guestfs_h *g; @@ -76,6 +77,8 @@ static void output_int64_uid (int64_t); static void output_string (const char *); static void output_string_link (const char *); +static const char *get_windows_root (); + static void __attribute__((noreturn)) usage (int status) { @@ -176,6 +179,7 @@ main (int argc, char *argv[]) #define MODE_LS_R 2 #define MODE_LS_LR (MODE_LS_L|MODE_LS_R) int mode = 0; + CLEANUP_FREE const char * win_root; g = guestfs_create (); if (g == NULL) { @@ -371,10 +375,18 @@ main (int argc, char *argv[]) free_drives (drvs); free_mps (mps); + win_root = get_windows_root (); + unsigned errors = 0; while (optind argc) { -const char *dir = argv[optind]; +CLEANUP_FREE const char *dir; + +if (win_root != NULL) { + dir = windows_path (g, win_root, argv[optind], 1 /* readonly */ ); +} else { + dir = safe_strdup (g, argv[optind]); +} switch (mode) { case 0: /* no -l or -R option */ @@ -409,6 +421,24 @@ main (int argc, char *argv[]) exit (errors == 0 ? EXIT_SUCCESS : EXIT_FAILURE); } +static const char * +get_windows_root (void) +{ + CLEANUP_FREE_STRING_LIST char **roots = NULL; + const char *root; + + roots = guestfs_inspect_get_roots (g); + assert (roots); + assert (roots[0] != NULL); + assert (roots[1] == NULL); + root = safe_strdup(g, roots[0]); + + if (is_windows (g, root)) +return root; + else +return NULL; +} + static int do_ls (const char *dir) { -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH] customize: add --copy
From: Maros Zatko hacx...@gmail.com This adds --copy SOURCE:DEST, equivalent of calling g#cp_a src dst. RFE: RHBZ#1203817 Maros Zatko (1): customize: add --copy builder/cmdline.ml | 2 +- customize/customize_run.ml | 4 generator/customize.ml | 10 ++ 3 files changed, 15 insertions(+), 1 deletion(-) -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH] customize: add --copy
From: Maros Zatko hacx...@gmail.com This adds --copy SOURCE:DEST, equivalent of calling g#cp_a src dst. RFE: RHBZ#1203817 --- builder/cmdline.ml | 2 +- customize/customize_run.ml | 4 generator/customize.ml | 10 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/builder/cmdline.ml b/builder/cmdline.ml index debc789..c863ad2 100644 --- a/builder/cmdline.ml +++ b/builder/cmdline.ml @@ -315,7 +315,7 @@ read the man page virt-builder(1). | `Password _ | `RootPassword _ | `Scrub _ | `SSHInject _ | `Timezone _ | `Truncate _ | `TruncateRecursive _ | `Upload _ | `Write _ | `Chmod _ - | `CommandsFromFile _ | `CopyIn _ - false + | `CommandsFromFile _ | `CopyIn _ | `Copy _ - false ) ops.ops in if requires_execute_on_guest then error (f_sorry, cannot run commands on a guest with a different architecture); diff --git a/customize/customize_run.ml b/customize/customize_run.ml index 73b4d8a..47dda72 100644 --- a/customize/customize_run.ml +++ b/customize/customize_run.ml @@ -171,6 +171,10 @@ exec %s 21 * read when their arguments are met. *) () +| `Copy (src, dest) - + msg (f_Copying (in image): %s to %s) src dest; + g#cp_a src dest + | `CopyIn (localpath, remotedir) - msg (f_Copying: %s to %s) localpath remotedir; g#copy_in localpath remotedir diff --git a/generator/customize.ml b/generator/customize.ml index bfb37f7..96c4c48 100644 --- a/generator/customize.ml +++ b/generator/customize.ml @@ -85,6 +85,16 @@ as if they were specified as I--delete /some/file on the command line.; }; + { op_name = copy; +op_type = StringPair SOURCE:DEST; +op_discrim = `Copy; +op_shortdesc = Copy files in disk image; +op_pod_longdesc = \ +Copy files or directories recursively inside the guest. + +Wildcards cannot be used.; + }; + { op_name = copy-in; op_type = StringPair LOCALPATH:REMOTEDIR; op_discrim = `CopyIn; -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH] customize: add --move
From: Maros Zatko hacx...@gmail.com This adds --move SOURCE:DEST, equivalent of calling g#mv src dst. RFE: RHBZ#1203817 Maros Zatko (1): customize: add --move builder/cmdline.ml | 2 +- customize/customize_run.ml | 4 generator/customize.ml | 10 ++ 3 files changed, 15 insertions(+), 1 deletion(-) -- 1.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] Inspection of disk snapshots
On Mon, Mar 23, 2015 at 10:41:01PM +, Richard W.M. Jones wrote: On Mon, Mar 23, 2015 at 04:34:21PM +0200, NoxDaFox wrote: Greetings, I have the following typical scenario: given one or more qcow2 base images I clone them with COW and start the VMs. At a certain point I'd like to inspect them in order to see their evolution compared to the known base images. To do so I was thinking about taking a disk snapshot of each VM and inspect its content through libguestfs (using it's Python bindings). Obviously I need the base image in order for libguestfs to correctly guess the OS, the FS structure etc.. Problem is that that point when I inspect the disk I get the whole disk state including the base image content (30K+ files and directories). This is not an issue but it's a very heavy operation considering that some of the snapshots are few megabytes while the base images are several gigabytes. Is there a way to programmatically instruct libguestfs to limit the inspection to the sole snapshot? Would it work as well with other disk format (vmdk linked clones for example)? For better comprehension I'll show the sequence I'm doing (I might do it wrong of course): virsh -c qemu:///system snapshot-create --disk-only domain-ID I get the snapshot location from its XML description and then: qemu-img convert -f qcow2 -O qcow2 base_image.qcow2 snapshot.qcow2 This makes a copy of the whole disk image. It's also not a consistent (point in time) copy. Oh I see that you're copying the _snapshot_ that you created with libvirt; it's not a whole disk copy. There's still not any point in doing this, and what I said below stands. At that point I mount it through libguestfs and inspect its content. As long as you use the 'readonly=1' flag (which is really *essential*, else you'll get disk corruption), you can just point libguestfs at the base image: g = guestfs.GuestFS (python_return_dict=True) g.add_drive_opts (base_image.qcow2, format=qcow2, readonly=1) That also doesn't get you a consistent snapshot, but it'll work most of the time, and give you a clear error in libguestfs when it doesn't (and won't corrupt your base disk or anything like that, provided you're using readonly=1). The effect of the readonly=1 flag is to create an external snapshot. It is roughly the equivalent of doing: qemu-img create -f qcow2 -b base_image snapshot.qcow2 point libguestfs at snapshot.qcow2 If you want lightweight, consistent, point-in-time snapshots (which it sounds like you do), qemu has recently been adding this capability. See the 'drive-backup' monitor command. I've not tried using that and I don't know if it is wired up through libvirt, but libguestfs should be able to consume it since it's just an NBD source. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH v2] New API: btrfs-image
-Original Message- From: Richard W.M. Jones [mailto:rjo...@redhat.com] Sent: Monday, March 23, 2015 9:32 PM To: Chen, Hanxiao/陈 晗霄 Cc: libguestfs@redhat.com Subject: Re: [Libguestfs] [PATCH v2] New API: btrfs-image On Tue, Mar 17, 2015 at 02:53:35AM -0400, Chen Hanxiao wrote: + /* btrfs-progs will valid numtheads and choose the right one for us */ + if ((optargs_bitmask GUESTFS_BTRFS_IMAGE_NUMTHREADS_BITMASK) + numthreads) { +snprintf (numthreads_s, sizeof numthreads_s, %d, numthreads); +ADD_ARG (argv, i, -t); +ADD_ARG (argv, i, numthreads_s); + } Can you get rid of this, as I think it's an implementation detail. We don't need to expose the -t/threads to API users. The patch is fine otherwise. OK, will fixed soon. Regards, - Chen ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v3] New API: btrfs-image
Signed-off-by: Chen Hanxiao chenhanx...@cn.fujitsu.com --- v3: remove optional paramter numthreads(-t) v2: add optargs_bitmask check daemon/btrfs.c | 43 +++ generator/actions.ml | 22 ++ src/MAX_PROC_NR | 2 +- 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/daemon/btrfs.c b/daemon/btrfs.c index fabb00b..39392f7 100644 --- a/daemon/btrfs.c +++ b/daemon/btrfs.c @@ -37,6 +37,7 @@ GUESTFSD_EXT_CMD(str_btrfstune, btrfstune); GUESTFSD_EXT_CMD(str_btrfsck, btrfsck); GUESTFSD_EXT_CMD(str_mkfs_btrfs, mkfs.btrfs); GUESTFSD_EXT_CMD(str_umount, umount); +GUESTFSD_EXT_CMD(str_btrfsimage, btrfs-image); int optgroup_btrfs_available (void) @@ -2040,3 +2041,45 @@ do_btrfstune_enable_skinny_metadata_extent_refs (const char *device) return 0; } + +int +do_btrfs_image (char *const *sources, const char *image, + int compresslevel) +{ + size_t nr_sources = count_strings (sources); + const size_t MAX_ARGS = 64 + nr_sources; + const char *argv[MAX_ARGS]; + size_t i = 0, j; + CLEANUP_FREE char *err = NULL; + CLEANUP_FREE char *out = NULL; + char compresslevel_s[64]; + int r; + + if (nr_sources == 0) { + reply_with_error (list of sources must be non-empty); + return -1; + } + + ADD_ARG (argv, i, str_btrfsimage); + + if ((optargs_bitmask GUESTFS_BTRFS_IMAGE_COMPRESSLEVEL_BITMASK) + compresslevel = 0) { +snprintf (compresslevel_s, sizeof compresslevel_s, %d, compresslevel); +ADD_ARG (argv, i, -c); +ADD_ARG (argv, i, compresslevel_s); + } + + for (j = 0; j nr_sources; ++j) +ADD_ARG (argv, i, sources[j]); + + ADD_ARG (argv, i, image); + ADD_ARG (argv, i, NULL); + + r = commandv (out, err, argv); + if (r == -1) { +reply_with_error (%s %s: %s, sources[0], image, err); +return -1; + } + + return 0; +} diff --git a/generator/actions.ml b/generator/actions.ml index 786b9a2..5e462a8 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -12527,6 +12527,28 @@ This will Enable extended inode refs. }; longdesc = \ This enable skinny metadata extent refs. }; + { defaults with +name = btrfs_image; +style = RErr, [DeviceList source; Pathname image], [OInt compresslevel]; +proc_nr = Some 453; +optional = Some btrfs; camel_name = BTRFSImage; +tests = [ + InitPartition, Always, TestRun ( +[[part_init; /dev/sda; mbr]; + [part_add; /dev/sda; p; 64; 204799]; + [part_add; /dev/sda; p; 204800; 409599]; + [mkfs_btrfs; /dev/sda1; ; ; NOARG; ; NOARG; NOARG; ; ]; + [mkfs_btrfs; /dev/sda2; ; ; NOARG; ; NOARG; NOARG; ; ]; + [mount; /dev/sda1; /]; + [btrfs_image; /dev/sda2; /1.img; ]; + [btrfs_image; /dev/sda2; /2.img; 2]]), [] +]; + +shortdesc = create an image of a btrfs filesystem; +longdesc = \ +This is used to create an image of a btrfs filesystem. +All data will be zeroed, but metadata and the like is preserved. }; + ] (* Non-API meta-commands available only in guestfish. diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index 8670c73..534b992 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -452 +453 -- 2.1.0 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs