Re: [Libguestfs] [PATCH] New API: part_get_part_type for showing partition type

2015-03-23 Thread Richard W.M. Jones
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

2015-03-23 Thread Richard W.M. Jones
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

2015-03-23 Thread Richard W.M. Jones

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

2015-03-23 Thread Richard W.M. Jones
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

2015-03-23 Thread Richard W.M. Jones
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

2015-03-23 Thread Richard W.M. Jones
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'

2015-03-23 Thread Richard W.M. Jones
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)

2015-03-23 Thread Richard W.M. Jones

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

2015-03-23 Thread Richard W.M. Jones
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

2015-03-23 Thread Richard W.M. Jones
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

2015-03-23 Thread Richard W.M. Jones
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

2015-03-23 Thread Maros Zatko
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

2015-03-23 Thread Maros Zatko
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

2015-03-23 Thread NoxDaFox
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

2015-03-23 Thread Maros Zatko

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

2015-03-23 Thread Richard W.M. Jones
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

2015-03-23 Thread Maros Zatko
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

2015-03-23 Thread Maros Zatko
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

2015-03-23 Thread Chen, Hanxiao


 -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

2015-03-23 Thread Maros Zatko
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

2015-03-23 Thread Maros Zatko
---
 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

2015-03-23 Thread Maros Zatko
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

2015-03-23 Thread Maros Zatko
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

2015-03-23 Thread Maros Zatko
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

2015-03-23 Thread Richard W.M. Jones
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

2015-03-23 Thread Chen, Hanxiao


 -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

2015-03-23 Thread Chen Hanxiao
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