[libvirt] [PATCH 0/2] mingw64 build fixes

I still don't have my mingw64 cross-compile working nicely, so although I'd like to push this under the build-breaker rule, I would feel safer waiting for Marc-André's test results. Eric Blake (2): build: use correct type for pid and similar types build: fix output of pid values cfg.mk | 6 ++++++ daemon/libvirtd.c | 4 ++-- include/libvirt/libvirt-qemu.h | 4 ++-- src/conf/domain_conf.h | 2 +- src/conf/storage_conf.c | 4 ++-- src/conf/storage_conf.h | 8 ++++---- src/driver.h | 3 ++- src/libvirt-qemu.c | 17 +++++++++++------ src/probes.d | 2 +- src/qemu/qemu_command.c | 13 +++++++------ src/qemu/qemu_command.h | 4 ++-- src/qemu/qemu_driver.c | 24 ++++++++++++++---------- src/qemu/qemu_process.c | 2 +- src/qemu/qemu_process.h | 2 +- src/qemu_protocol-structs | 2 +- src/remote/qemu_protocol.x | 4 ++-- src/rpc/virnetsocket.c | 12 ++++++------ src/security/security_dac.c | 27 ++++++++++++++++----------- src/uml/uml_driver.c | 6 +++--- src/util/cgroup.c | 17 +++++++++-------- src/util/command.c | 20 +++++++++----------- src/util/virnetdev.c | 4 ++-- src/util/virnetdev.h | 2 +- src/vmware/vmware_conf.c | 10 ++++++---- tests/testutils.c | 2 +- tools/virsh.c | 10 +++++----- 26 files changed, 117 insertions(+), 94 deletions(-) -- 1.7.7.6

No thanks to 64-bit windows, with 64-bit pid_t, we have to avoid constructs like 'int pid'. Our API in libvirt-qemu cannot be changed without breaking ABI; but then again, libvirt-qemu can only be used on systems that support UNIX sockets, which rules out Windows (even if qemu could be compiled there) - so for all points on the call chain that interact with this API decision, we require a different variable name to make it clear that we audited the use for safety. Adding a syntax-check rule only solves half the battle; anywhere that uses printf on a pid_t still needs to be converted, but that will be a separate patch. * cfg.mk (sc_correct_id_types): New syntax check. * src/libvirt-qemu.c (virDomainQemuAttach): Document why we didn't use pid_t for pid, and validate for overflow. * include/libvirt/libvirt-qemu.h (virDomainQemuAttach): Tweak name for syntax check. * src/vmware/vmware_conf.c (vmwareExtractPid): Likewise. * src/driver.h (virDrvDomainQemuAttach): Likewise. * tools/virsh.c (cmdQemuAttach): Likewise. * src/remote/qemu_protocol.x (qemu_domain_attach_args): Likewise. * src/qemu_protocol-structs (qemu_domain_attach_args): Likewise. * src/util/cgroup.c (virCgroupPidCode, virCgroupKillInternal): Likewise. * src/qemu/qemu_command.c(qemuParseProcFileStrings): Likewise. (qemuParseCommandLinePid): Use pid_t for pid. * daemon/libvirtd.c (daemonForkIntoBackground): Likewise. * src/conf/domain_conf.h (_virDomainObj): Likewise. * src/probes.d (rpc_socket_new): Likewise. * src/qemu/qemu_command.h (qemuParseCommandLinePid): Likewise. * src/qemu/qemu_driver.c (qemudGetProcessInfo, qemuDomainAttach): Likewise. * src/qemu/qemu_process.c (qemuProcessAttach): Likewise. * src/qemu/qemu_process.h (qemuProcessAttach): Likewise. * src/uml/uml_driver.c (umlGetProcessInfo): Likewise. * src/util/virnetdev.h (virNetDevSetNamespace): Likewise. * src/util/virnetdev.c (virNetDevSetNamespace): Likewise. * tests/testutils.c (virtTestCaptureProgramOutput): Likewise. * src/conf/storage_conf.h (_virStoragePerms): Use mode_t, uid_t, and gid_t rather than int. * src/security/security_dac.c (virSecurityDACSetOwnership): Likewise. * src/conf/storage_conf.c (virStorageDefParsePerms): Avoid compiler warning. --- cfg.mk | 6 ++++++ daemon/libvirtd.c | 4 ++-- include/libvirt/libvirt-qemu.h | 4 ++-- src/conf/domain_conf.h | 2 +- src/conf/storage_conf.c | 4 ++-- src/conf/storage_conf.h | 8 ++++---- src/driver.h | 3 ++- src/libvirt-qemu.c | 17 +++++++++++------ src/probes.d | 2 +- src/qemu/qemu_command.c | 13 +++++++------ src/qemu/qemu_command.h | 4 ++-- src/qemu/qemu_driver.c | 24 ++++++++++++++---------- src/qemu/qemu_process.c | 2 +- src/qemu/qemu_process.h | 2 +- src/qemu_protocol-structs | 2 +- src/remote/qemu_protocol.x | 4 ++-- src/security/security_dac.c | 27 ++++++++++++++++----------- src/uml/uml_driver.c | 6 +++--- src/util/cgroup.c | 17 +++++++++-------- src/util/virnetdev.c | 4 ++-- src/util/virnetdev.h | 2 +- src/vmware/vmware_conf.c | 10 ++++++---- tests/testutils.c | 2 +- tools/virsh.c | 10 +++++----- 24 files changed, 102 insertions(+), 77 deletions(-) diff --git a/cfg.mk b/cfg.mk index dcf44bb..9e50a5a 100644 --- a/cfg.mk +++ b/cfg.mk @@ -416,6 +416,12 @@ sc_prohibit_ctype_h: halt="don't use ctype.h; instead, use c-ctype.h" \ $(_sc_search_regexp) +# Insist on correct types for [pug]id. +sc_correct_id_types: + @prohibit='\<(int|long) *[pug]id\>' \ + halt="use pid_t for pid, uid_t for uid, gid_t for gid" \ + $(_sc_search_regexp) + # Ensure that no C source file, docs, or rng schema uses TABs for # indentation. Also match *.h.in files, to get libvirt.h.in. Exclude # files in gnulib, since they're imported. diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index b1b542b..db2977e 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -1,7 +1,7 @@ /* * libvirtd.c: daemon start of day, guest process & i/o management * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -186,7 +186,7 @@ static int daemonForkIntoBackground(const char *argv0) if (pipe(statuspipe) < 0) return -1; - int pid = fork(); + pid_t pid = fork(); switch (pid) { case 0: { diff --git a/include/libvirt/libvirt-qemu.h b/include/libvirt/libvirt-qemu.h index 7f12e4f..ba75ae3 100644 --- a/include/libvirt/libvirt-qemu.h +++ b/include/libvirt/libvirt-qemu.h @@ -4,7 +4,7 @@ * Description: Provides the interfaces of the libvirt library to handle * qemu specific methods * - * Copy: Copyright (C) 2010 Red Hat, Inc. + * Copy: Copyright (C) 2010, 2012 Red Hat, Inc. * * See COPYING.LIB for the License of this software * @@ -29,7 +29,7 @@ int virDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd, char **result, unsigned int flags); virDomainPtr virDomainQemuAttach(virConnectPtr domain, - unsigned int pid, + unsigned int pid_value, unsigned int flags); # ifdef __cplusplus diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8bb21cf..0ef76a2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1675,7 +1675,7 @@ struct _virDomainObj { virMutex lock; int refs; - int pid; + pid_t pid; virDomainStateReason state; unsigned int autostart : 1; diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index dadc115..40172d2 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -1,7 +1,7 @@ /* * storage_conf.c: config handling for storage driver * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006-2008 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -572,7 +572,7 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt, } else { char *end = NULL; perms->mode = strtol(mode, &end, 8); - if (*end || perms->mode < 0 || perms->mode > 0777) { + if (*end || (perms->mode & ~0777)) { VIR_FREE(mode); virStorageReportError(VIR_ERR_XML_ERROR, "%s", _("malformed octal mode")); diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 19bbd2c..303d4a5 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -1,7 +1,7 @@ /* * storage_conf.h: config handling for storage driver * - * Copyright (C) 2006-2008, 2010-2011 Red Hat, Inc. + * Copyright (C) 2006-2008, 2010-2012 Red Hat, Inc. * Copyright (C) 2006-2008 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -38,9 +38,9 @@ typedef struct _virStoragePerms virStoragePerms; typedef virStoragePerms *virStoragePermsPtr; struct _virStoragePerms { - int mode; - int uid; - int gid; + mode_t mode; + uid_t uid; + gid_t gid; char *label; }; diff --git a/src/driver.h b/src/driver.h index d27fa99..5de1f3e 100644 --- a/src/driver.h +++ b/src/driver.h @@ -658,9 +658,10 @@ typedef int (*virDrvDomainQemuMonitorCommand)(virDomainPtr domain, const char *cmd, char **result, unsigned int flags); +/* Choice of unsigned int rather than pid_t is intentional. */ typedef virDomainPtr (*virDrvDomainQemuAttach)(virConnectPtr conn, - unsigned int pid, + unsigned int pid_value, unsigned int flags); typedef int diff --git a/src/libvirt-qemu.c b/src/libvirt-qemu.c index 248cc33..5267bba 100644 --- a/src/libvirt-qemu.c +++ b/src/libvirt-qemu.c @@ -2,7 +2,7 @@ * libvirt-qemu.c: Interfaces for the libvirt library to handle qemu-specific * APIs. * - * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright (C) 2010-2012 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -116,7 +116,7 @@ error: /** * virDomainQemuAttach: * @conn: pointer to a hypervisor connection - * @pid: the UNIX process ID of the external QEMU process + * @pid_value: the UNIX process ID of the external QEMU process * @flags: optional flags, currently unused * * This API is QEMU specific, so it will only work with hypervisor @@ -133,6 +133,10 @@ error: * - The '-name' and '-uuid' arguments should have been set (not * mandatory, but strongly recommended) * + * To date, the only platforms we know of where pid_t is larger than + * unsigned int (64-bit Windows) also lack UNIX sockets, so the choice + * of @pid_value as an unsigned int should not present any difficulties. + * * If successful, then the guest will appear in the list of running * domains for this connection, and other APIs should operate * normally (provided the above requirements were honored). @@ -141,10 +145,11 @@ error: */ virDomainPtr virDomainQemuAttach(virConnectPtr conn, - unsigned int pid, + unsigned int pid_value, unsigned int flags) { - VIR_DEBUG("conn=%p, pid=%u, flags=%x", conn, pid, flags); + pid_t pid = pid_value; + VIR_DEBUG("conn=%p, pid=%u, flags=%x", conn, pid_value, flags); virResetLastError(); @@ -154,7 +159,7 @@ virDomainQemuAttach(virConnectPtr conn, return NULL; } - if (pid <= 1) { + if (pid != pid_value || pid <= 1) { virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__); goto error; } @@ -166,7 +171,7 @@ virDomainQemuAttach(virConnectPtr conn, if (conn->driver->qemuDomainAttach) { virDomainPtr ret; - ret = conn->driver->qemuDomainAttach(conn, pid, flags); + ret = conn->driver->qemuDomainAttach(conn, pid_value, flags); if (!ret) goto error; return ret; diff --git a/src/probes.d b/src/probes.d index 64abc57..9d70cc9 100644 --- a/src/probes.d +++ b/src/probes.d @@ -18,7 +18,7 @@ provider libvirt { # file: src/rpc/virnetsocket.c # prefix: rpc - probe rpc_socket_new(void *sock, int refs, int fd, int errfd, int pid, const char *localAddr, const char *remoteAddr); + probe rpc_socket_new(void *sock, int refs, int fd, int errfd, pid_t pid, const char *localAddr, const char *remoteAddr); probe rpc_socket_send_fd(void *sock, int fd); probe rpc_socket_recv_fd(void *sock, int fd); probe rpc_socket_ref(void *sock, int refs); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1b92aa4..2e63193 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7845,7 +7845,7 @@ cleanup: } -static int qemuParseProcFileStrings(unsigned int pid, +static int qemuParseProcFileStrings(unsigned int pid_value, const char *name, const char ***list) { @@ -7858,7 +7858,7 @@ static int qemuParseProcFileStrings(unsigned int pid, const char **str = NULL; int i; - if (virAsprintf(&path, "/proc/%u/%s", pid, name) < 0) { + if (virAsprintf(&path, "/proc/%u/%s", pid_value, name) < 0) { virReportOOMError(); goto cleanup; } @@ -7905,7 +7905,7 @@ cleanup: } virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, - unsigned int pid, + pid_t pid, char **pidfile, virDomainChrSourceDefPtr *monConfig, bool *monJSON) @@ -7917,7 +7917,8 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, char *emulator; int i; - if (qemuParseProcFileStrings(pid, "cmdline", &progargv) < 0 || + if ((unsigned int) pid != pid || + qemuParseProcFileStrings(pid, "cmdline", &progargv) < 0 || qemuParseProcFileStrings(pid, "environ", &progenv) < 0) goto cleanup; @@ -7925,7 +7926,7 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, pidfile, monConfig, monJSON))) goto cleanup; - if (virAsprintf(&exepath, "/proc/%u/exe", pid) < 0) { + if (virAsprintf(&exepath, "/proc/%u/exe", (int) pid) < 0) { virReportOOMError(); goto cleanup; } @@ -7933,7 +7934,7 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, if (virFileResolveLink(exepath, &emulator) < 0) { virReportSystemError(errno, _("Unable to resolve %s for pid %u"), - exepath, pid); + exepath, (int) pid); goto cleanup; } VIR_FREE(def->emulator); diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 2f8b5ba..02aa6d3 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -1,7 +1,7 @@ /* * qemu_command.h: QEMU command generation * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -169,7 +169,7 @@ virDomainDefPtr qemuParseCommandLineString(virCapsPtr caps, virDomainChrSourceDefPtr *monConfig, bool *monJSON); virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, - unsigned int pid, + pid_t pid, char **pidfile, virDomainChrSourceDefPtr *monConfig, bool *monJSON); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 160cb37..abe73f1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1056,7 +1056,7 @@ cleanup: static int qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss, - int pid, int tid) + pid_t pid, int tid) { char *proc; FILE *pidinfo; @@ -1065,10 +1065,12 @@ qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss, int cpu; int ret; + /* In general, we cannot assume pid_t fits in int; but /proc parsing + * is specific to Linux where int works fine. */ if (tid) - ret = virAsprintf(&proc, "/proc/%d/task/%d/stat", pid, tid); + ret = virAsprintf(&proc, "/proc/%d/task/%d/stat", (int) pid, tid); else - ret = virAsprintf(&proc, "/proc/%d/stat", pid); + ret = virAsprintf(&proc, "/proc/%d/stat", (int) pid); if (ret < 0) return -1; @@ -1120,7 +1122,7 @@ qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss, VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%ld", - pid, tid, usertime, systime, cpu, rss); + (int) pid, tid, usertime, systime, cpu, rss); VIR_FORCE_FCLOSE(pidinfo); @@ -11146,7 +11148,7 @@ cleanup: static virDomainPtr qemuDomainAttach(virConnectPtr conn, - unsigned int pid, + unsigned int pid_value, unsigned int flags) { struct qemud_driver *driver = conn->privateData; @@ -11155,6 +11157,7 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn, virDomainPtr dom = NULL; virDomainChrSourceDefPtr monConfig = NULL; bool monJSON = false; + pid_t pid = pid_value; char *pidfile = NULL; virCheckFlags(0, NULL); @@ -11167,19 +11170,20 @@ static virDomainPtr qemuDomainAttach(virConnectPtr conn, if (!monConfig) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("No monitor connection for pid %u"), - pid); + _("No monitor connection for pid %u"), pid_value); goto cleanup; } if (monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Cannot connect to monitor connection of type '%s' for pid %u"), - virDomainChrTypeToString(monConfig->type), pid); + _("Cannot connect to monitor connection of type '%s' " + "for pid %u"), + virDomainChrTypeToString(monConfig->type), + pid_value); goto cleanup; } if (!(def->name) && - virAsprintf(&def->name, "attach-pid-%u", pid) < 0) { + virAsprintf(&def->name, "attach-pid-%u", pid_value) < 0) { virReportOOMError(); goto cleanup; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 2d92d66..d9f56ba 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3798,7 +3798,7 @@ retry: int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED, struct qemud_driver *driver, virDomainObjPtr vm, - int pid, + pid_t pid, const char *pidfile, virDomainChrSourceDefPtr monConfig, bool monJSON) diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index 4ae6b4b..8175012 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -63,7 +63,7 @@ void qemuProcessStop(struct qemud_driver *driver, int qemuProcessAttach(virConnectPtr conn, struct qemud_driver *driver, virDomainObjPtr vm, - int pid, + pid_t pid, const char *pidfile, virDomainChrSourceDefPtr monConfig, bool monJSON); diff --git a/src/qemu_protocol-structs b/src/qemu_protocol-structs index 0397471..67968eb 100644 --- a/src/qemu_protocol-structs +++ b/src/qemu_protocol-structs @@ -13,7 +13,7 @@ struct qemu_monitor_command_ret { remote_nonnull_string result; }; struct qemu_domain_attach_args { - u_int pid; + u_int pid_value; u_int flags; }; struct qemu_domain_attach_ret { diff --git a/src/remote/qemu_protocol.x b/src/remote/qemu_protocol.x index 39f9adf..5afe680 100644 --- a/src/remote/qemu_protocol.x +++ b/src/remote/qemu_protocol.x @@ -3,7 +3,7 @@ * remote_internal driver and libvirtd. This protocol is * internal and may change at any time. * - * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright (C) 2010-2012 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,7 +39,7 @@ struct qemu_monitor_command_ret { struct qemu_domain_attach_args { - unsigned int pid; + unsigned int pid_value; unsigned int flags; }; diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 3e1a72f..e71dc20 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 Red Hat, Inc. + * Copyright (C) 2010-2012 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -94,9 +94,10 @@ static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNU } static int -virSecurityDACSetOwnership(const char *path, int uid, int gid) +virSecurityDACSetOwnership(const char *path, uid_t uid, gid_t gid) { - VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'", path, uid, gid); + VIR_INFO("Setting DAC user and group on '%s' to '%ld:%ld'", + path, (long) uid, (long) gid); if (chown(path, uid, gid) < 0) { struct stat sb; @@ -111,18 +112,22 @@ virSecurityDACSetOwnership(const char *path, int uid, int gid) } if (chown_errno == EOPNOTSUPP || chown_errno == EINVAL) { - VIR_INFO("Setting user and group to '%d:%d' on '%s' not supported by filesystem", - uid, gid, path); + VIR_INFO("Setting user and group to '%ld:%ld' on '%s' not " + "supported by filesystem", + (long) uid, (long) gid, path); } else if (chown_errno == EPERM) { - VIR_INFO("Setting user and group to '%d:%d' on '%s' not permitted", - uid, gid, path); + VIR_INFO("Setting user and group to '%ld:%ld' on '%s' not " + "permitted", + (long) uid, (long) gid, path); } else if (chown_errno == EROFS) { - VIR_INFO("Setting user and group to '%d:%d' on '%s' not possible on readonly filesystem", - uid, gid, path); + VIR_INFO("Setting user and group to '%ld:%ld' on '%s' not " + "possible on readonly filesystem", + (long) uid, (long) gid, path); } else { virReportSystemError(chown_errno, - _("unable to set user and group to '%d:%d' on '%s'"), - uid, gid, path); + _("unable to set user and group to '%ld:%ld' " + "on '%s'"), + (long) uid, (long) gid, path); return -1; } } diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index a4cf945..24ee01e 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1,7 +1,7 @@ /* * uml_driver.c: core driver methods for managing UML guests * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006-2008 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -1239,13 +1239,13 @@ static char *umlGetCapabilities(virConnectPtr conn) { -static int umlGetProcessInfo(unsigned long long *cpuTime, int pid) +static int umlGetProcessInfo(unsigned long long *cpuTime, pid_t pid) { char *proc; FILE *pidinfo; unsigned long long usertime, systime; - if (virAsprintf(&proc, "/proc/%d/stat", pid) < 0) { + if (virAsprintf(&proc, "/proc/%lld/stat", (long long) pid) < 0) { return -1; } diff --git a/src/util/cgroup.c b/src/util/cgroup.c index 15b870d..00528c5 100644 --- a/src/util/cgroup.c +++ b/src/util/cgroup.c @@ -1598,19 +1598,20 @@ static int virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr goto cleanup; } else { while (!feof(fp)) { - unsigned long pid; - if (fscanf(fp, "%lu", &pid) != 1) { + unsigned long pid_value; + if (fscanf(fp, "%lu", &pid_value) != 1) { if (feof(fp)) break; rc = -errno; VIR_DEBUG("Failed to read %s: %m\n", keypath); goto cleanup; } - if (virHashLookup(pids, (void*)pid)) + if (virHashLookup(pids, (void*)pid_value)) continue; - VIR_DEBUG("pid=%lu", pid); - if (kill((pid_t)pid, signum) < 0) { + VIR_DEBUG("pid=%lu", pid_value); + /* Cgroups is a Linux concept, so this cast is safe. */ + if (kill((pid_t)pid_value, signum) < 0) { if (errno != ESRCH) { rc = -errno; goto cleanup; @@ -1621,7 +1622,7 @@ static int virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr done = false; } - ignore_value(virHashAddEntry(pids, (void*)pid, (void*)1)); + ignore_value(virHashAddEntry(pids, (void*)pid_value, (void*)1)); } VIR_FORCE_FCLOSE(fp); } @@ -1639,8 +1640,8 @@ cleanup: static uint32_t virCgroupPidCode(const void *name, uint32_t seed) { - unsigned long pid = (unsigned long)(intptr_t)name; - return virHashCodeGen(&pid, sizeof(pid), seed); + unsigned long pid_value = (unsigned long)(intptr_t)name; + return virHashCodeGen(&pid_value, sizeof(pid_value), seed); } static bool virCgroupPidEqual(const void *namea, const void *nameb) { diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c index 9d76d47..4aa7639 100644 --- a/src/util/virnetdev.c +++ b/src/util/virnetdev.c @@ -443,7 +443,7 @@ int virNetDevSetMTUFromDevice(const char *ifname, * * Returns 0 on success or -1 in case of error */ -int virNetDevSetNamespace(const char *ifname, int pidInNs) +int virNetDevSetNamespace(const char *ifname, pid_t pidInNs) { int rc; char *pid = NULL; @@ -451,7 +451,7 @@ int virNetDevSetNamespace(const char *ifname, int pidInNs) "ip", "link", "set", ifname, "netns", NULL, NULL }; - if (virAsprintf(&pid, "%d", pidInNs) == -1) { + if (virAsprintf(&pid, "%lld", (long long) pidInNs) == -1) { virReportOOMError(); return -1; } diff --git a/src/util/virnetdev.h b/src/util/virnetdev.h index 7845e25..3456113 100644 --- a/src/util/virnetdev.h +++ b/src/util/virnetdev.h @@ -73,7 +73,7 @@ int virNetDevSetMTUFromDevice(const char *ifname, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; int virNetDevGetMTU(const char *ifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -int virNetDevSetNamespace(const char *ifname, int pidInNs) +int virNetDevSetNamespace(const char *ifname, pid_t pidInNs) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; int virNetDevSetName(const char *ifname, const char *newifname) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c index 3680ca0..847d146 100644 --- a/src/vmware/vmware_conf.c +++ b/src/vmware/vmware_conf.c @@ -1,6 +1,6 @@ /*---------------------------------------------------------------------------*/ /* - * Copyright (C) 2011 Red Hat, Inc. + * Copyright (C) 2011-2012 Red Hat, Inc. * Copyright 2010, diateam (www.diateam.net) * * This library is free software; you can redistribute it and/or @@ -457,7 +457,7 @@ vmwareExtractPid(const char * vmxPath) FILE *logFile = NULL; char line[1024]; char *tmp = NULL; - int pid = -1; + int pid_value = -1; if ((vmxDir = mdir_name(vmxPath)) == NULL) goto cleanup; @@ -485,7 +485,9 @@ vmwareExtractPid(const char * vmxPath) tmp += strlen(" pid="); - if (virStrToLong_i(tmp, &tmp, 10, &pid) < 0 || *tmp != ' ') { + /* Although 64-bit windows allows 64-bit pid_t, a domain id has to be + * 32 bits. For now, we just reject pid values that overflow int. */ + if (virStrToLong_i(tmp, &tmp, 10, &pid_value) < 0 || *tmp != ' ') { vmwareError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot parse pid in vmware log file")); goto cleanup; @@ -495,7 +497,7 @@ cleanup: VIR_FREE(vmxDir); VIR_FREE(logFilePath); VIR_FORCE_FCLOSE(logFile); - return pid; + return pid_value; } char * diff --git a/tests/testutils.c b/tests/testutils.c index 8678546..4b224ee 100644 --- a/tests/testutils.c +++ b/tests/testutils.c @@ -294,7 +294,7 @@ virtTestCaptureProgramOutput(const char *const argv[], char **buf, int maxlen) if (pipe(pipefd) < 0) return -1; - int pid = fork(); + pid_t pid = fork(); switch (pid) { case 0: VIR_FORCE_CLOSE(pipefd[0]); diff --git a/tools/virsh.c b/tools/virsh.c index 66ba61c..389d115 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -16397,26 +16397,26 @@ cmdQemuAttach(vshControl *ctl, const vshCmd *cmd) virDomainPtr dom = NULL; bool ret = false; unsigned int flags = 0; - unsigned int pid; + unsigned int pid_value; /* API uses unsigned int, not pid_t */ if (!vshConnectionUsability(ctl, ctl->conn)) goto cleanup; - if (vshCommandOptUInt(cmd, "pid", &pid) <= 0) { + if (vshCommandOptUInt(cmd, "pid", &pid_value) <= 0) { vshError(ctl, "%s", _("missing pid value")); goto cleanup; } - if (!(dom = virDomainQemuAttach(ctl->conn, pid, flags))) + if (!(dom = virDomainQemuAttach(ctl->conn, pid_value, flags))) goto cleanup; if (dom != NULL) { vshPrint(ctl, _("Domain %s attached to pid %u\n"), - virDomainGetName(dom), pid); + virDomainGetName(dom), pid_value); virDomainFree(dom); ret = true; } else { - vshError(ctl, _("Failed to attach to pid %u"), pid); + vshError(ctl, _("Failed to attach to pid %u"), pid_value); } cleanup: -- 1.7.7.6

On 02/11/2012 12:55 AM, Eric Blake wrote:
No thanks to 64-bit windows, with 64-bit pid_t, we have to avoid constructs like 'int pid'. Our API in libvirt-qemu cannot be changed without breaking ABI; but then again, libvirt-qemu can only be used on systems that support UNIX sockets, which rules out Windows (even if qemu could be compiled there) - so for all points on the call chain that interact with this API decision, we require a different variable name to make it clear that we audited the use for safety.
Adding a syntax-check rule only solves half the battle; anywhere that uses printf on a pid_t still needs to be converted, but that will be a separate patch.
Sorry for remembering really late to review your patch.
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1b92aa4..2e63193 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7925,7 +7926,7 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, pidfile, monConfig, monJSON))) goto cleanup;
- if (virAsprintf(&exepath, "/proc/%u/exe", pid)< 0) { + if (virAsprintf(&exepath, "/proc/%u/exe", (int) pid)< 0) {
I'd use "/proc/%lld/exe" and cast pid to (long long). Or at least change "%u" to "%d" for the (int) typecast. I agree that linux does not use long pids now, but it's nicer when the code is uniform and you used the long long variant later on and in the 2/2 patch of this series.
virReportOOMError(); goto cleanup; } @@ -7933,7 +7934,7 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, if (virFileResolveLink(exepath,&emulator)< 0) { virReportSystemError(errno, _("Unable to resolve %s for pid %u"), - exepath, pid); + exepath, (int) pid);
Same as above.
goto cleanup; } VIR_FREE(def->emulator);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 160cb37..abe73f1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -1065,10 +1065,12 @@ qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss, int cpu; int ret;
+ /* In general, we cannot assume pid_t fits in int; but /proc parsing + * is specific to Linux where int works fine. */
The format string is correct here
if (tid) - ret = virAsprintf(&proc, "/proc/%d/task/%d/stat", pid, tid); + ret = virAsprintf(&proc, "/proc/%d/task/%d/stat", (int) pid, tid); else - ret = virAsprintf(&proc, "/proc/%d/stat", pid); + ret = virAsprintf(&proc, "/proc/%d/stat", (int) pid); if (ret< 0) return -1;
@@ -1120,7 +1122,7 @@ qemudGetProcessInfo(unsigned long long *cpuTime, int *lastCpu, long *vm_rss,
VIR_DEBUG("Got status for %d/%d user=%llu sys=%llu cpu=%d rss=%ld", - pid, tid, usertime, systime, cpu, rss); + (int) pid, tid, usertime, systime, cpu, rss);
VIR_FORCE_FCLOSE(pidinfo);
diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 3e1a72f..e71dc20 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -94,9 +94,10 @@ static const char * virSecurityDACGetDOI(virSecurityManagerPtr mgr ATTRIBUTE_UNU }
static int -virSecurityDACSetOwnership(const char *path, int uid, int gid) +virSecurityDACSetOwnership(const char *path, uid_t uid, gid_t gid) { - VIR_INFO("Setting DAC user and group on '%s' to '%d:%d'", path, uid, gid); + VIR_INFO("Setting DAC user and group on '%s' to '%ld:%ld'", + path, (long) uid, (long) gid);
if (chown(path, uid, gid)< 0) { struct stat sb; @@ -111,18 +112,22 @@ virSecurityDACSetOwnership(const char *path, int uid, int gid) }
if (chown_errno == EOPNOTSUPP || chown_errno == EINVAL) { - VIR_INFO("Setting user and group to '%d:%d' on '%s' not supported by filesystem", - uid, gid, path); + VIR_INFO("Setting user and group to '%ld:%ld' on '%s' not " + "supported by filesystem", + (long) uid, (long) gid, path); } else if (chown_errno == EPERM) { - VIR_INFO("Setting user and group to '%d:%d' on '%s' not permitted", - uid, gid, path); + VIR_INFO("Setting user and group to '%ld:%ld' on '%s' not " + "permitted", + (long) uid, (long) gid, path); } else if (chown_errno == EROFS) { - VIR_INFO("Setting user and group to '%d:%d' on '%s' not possible on readonly filesystem", - uid, gid, path); + VIR_INFO("Setting user and group to '%ld:%ld' on '%s' not " + "possible on readonly filesystem", + (long) uid, (long) gid, path); } else { virReportSystemError(chown_errno, - _("unable to set user and group to '%d:%d' on '%s'"), - uid, gid, path); + _("unable to set user and group to '%ld:%ld' " + "on '%s'"), + (long) uid, (long) gid, path); return -1; } }
Again, I'd prefer long longs here to line up with other instances.
ACK with the mismatch of signedness of the formating string and typecast in the first and second hunk of this reply. The other comments are just cosmetic so I'm ok if you leave the rest as is. Peter

On 03/02/2012 05:42 AM, Peter Krempa wrote:
Sorry for remembering really late to review your patch.
No problem. There's still some work to do to get things happy now that F17 has switched cross toolchains to mingw64.
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 1b92aa4..2e63193 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -7925,7 +7926,7 @@ virDomainDefPtr qemuParseCommandLinePid(virCapsPtr caps, pidfile, monConfig, monJSON))) goto cleanup;
- if (virAsprintf(&exepath, "/proc/%u/exe", pid)< 0) { + if (virAsprintf(&exepath, "/proc/%u/exe", (int) pid)< 0) {
I'd use "/proc/%lld/exe" and cast pid to (long long). Or at least change "%u" to "%d" for the (int) typecast. I agree that linux does not use long pids now, but it's nicer when the code is uniform and you used the long long variant later on and in the 2/2 patch of this series.
I'll go with the short %d, along with a comment why it is safe.
virReportSystemError(chown_errno, - _("unable to set user and group to '%d:%d' on '%s'"), - uid, gid, path); + _("unable to set user and group to '%ld:%ld' " + "on '%s'"), + (long) uid, (long) gid, path); return -1; } }
Again, I'd prefer long longs here to line up with other instances.
We already have a compile-time assertion that uid_t and gid_t fit in long, and this is true for all known platforms including ming64. It is only pid_t (and thus id_t) that is problematic. We also have other instances of commits that just cast to long when printing uids, so if I were to make things consistent with long long, I'd have to touch more code. So I don't think this one is worth changing.
ACK with the mismatch of signedness of the formating string and typecast in the first and second hunk of this reply. The other comments are just cosmetic so I'm ok if you leave the rest as is.
Sounds like I'll just fix the first two hunks, then :) -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

Nuke the last vestiges of printing pid_t values with the wrong types, at least in code compiled on mingw64. There may be other places, but for now they are only compiled on systems where the existing %d doesn't trigger gcc warnings. * src/rpc/virnetsocket.c (virNetSocketNew): Use %lld and casting, rather than assuming any particular int type for pid_t. * src/util/command.c (virCommandRunAsync, virPidWait) (virPidAbort): Likewise. (verify): Drop a now stale assertion. --- src/rpc/virnetsocket.c | 12 ++++++------ src/util/command.c | 20 +++++++++----------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c index 67d33b7..af3f9ac 100644 --- a/src/rpc/virnetsocket.c +++ b/src/rpc/virnetsocket.c @@ -1,7 +1,7 @@ /* * virnetsocket.c: generic network socket handling * - * Copyright (C) 2006-2011 Red Hat, Inc. + * Copyright (C) 2006-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -114,9 +114,9 @@ static virNetSocketPtr virNetSocketNew(virSocketAddrPtr localAddr, virNetSocketPtr sock; int no_slow_start = 1; - VIR_DEBUG("localAddr=%p remoteAddr=%p fd=%d errfd=%d pid=%d", + VIR_DEBUG("localAddr=%p remoteAddr=%p fd=%d errfd=%d pid=%lld", localAddr, remoteAddr, - fd, errfd, pid); + fd, errfd, (long long) pid); if (virSetCloseExec(fd) < 0) { virReportSystemError(errno, "%s", @@ -174,9 +174,9 @@ static virNetSocketPtr virNetSocketNew(virSocketAddrPtr localAddr, sock->client = isClient; PROBE(RPC_SOCKET_NEW, - "sock=%p refs=%d fd=%d errfd=%d pid=%d localAddr=%s, remoteAddr=%s", - sock, sock->refs, fd, errfd, - pid, NULLSTR(sock->localAddrStr), NULLSTR(sock->remoteAddrStr)); + "sock=%p refs=%d fd=%d errfd=%d pid=%lld localAddr=%s, remoteAddr=%s", + sock, sock->refs, fd, errfd, (long long) pid, + NULLSTR(sock->localAddrStr), NULLSTR(sock->remoteAddrStr)); return sock; diff --git a/src/util/command.c b/src/util/command.c index a2d5f84..b752b2a 100644 --- a/src/util/command.c +++ b/src/util/command.c @@ -42,7 +42,6 @@ #include "virpidfile.h" #include "buf.h" #include "ignore-value.h" -#include "verify.h" #define VIR_FROM_THIS VIR_FROM_NONE @@ -50,9 +49,6 @@ virReportErrorHelper(VIR_FROM_NONE, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__) -/* We have quite a bit of changes to make if this doesn't hold. */ -verify(sizeof(pid_t) <= sizeof(int)); - /* Flags for virExecWithHook */ enum { VIR_EXEC_NONE = 0, @@ -2152,8 +2148,8 @@ virCommandRunAsync(virCommandPtr cmd, pid_t *pid) if (cmd->pid != -1) { virCommandError(VIR_ERR_INTERNAL_ERROR, - _("command is already running as pid %d"), - cmd->pid); + _("command is already running as pid %lld"), + (long long) cmd->pid); return -1; } @@ -2228,7 +2224,8 @@ virPidWait(pid_t pid, int *exitstatus) int status; if (pid <= 0) { - virReportSystemError(EINVAL, _("unable to wait for process %d"), pid); + virReportSystemError(EINVAL, _("unable to wait for process %lld"), + (long long) pid); return -1; } @@ -2237,7 +2234,8 @@ virPidWait(pid_t pid, int *exitstatus) errno == EINTR); if (ret == -1) { - virReportSystemError(errno, _("unable to wait for process %d"), pid); + virReportSystemError(errno, _("unable to wait for process %lld"), + (long long) pid); return -1; } @@ -2245,8 +2243,8 @@ virPidWait(pid_t pid, int *exitstatus) if (status != 0) { char *st = virCommandTranslateStatus(status); virCommandError(VIR_ERR_INTERNAL_ERROR, - _("Child process (%d) status unexpected: %s"), - pid, NULLSTR(st)); + _("Child process (%lld) status unexpected: %s"), + (long long) pid, NULLSTR(st)); VIR_FREE(st); return -1; } @@ -2371,7 +2369,7 @@ virPidAbort(pid_t pid) } } } - VIR_DEBUG("failed to reap child %d, abandoning it", pid); + VIR_DEBUG("failed to reap child %lld, abandoning it", (long long) pid); cleanup: VIR_FREE(tmp); -- 1.7.7.6

On 02/11/2012 12:55 AM, Eric Blake wrote:
Nuke the last vestiges of printing pid_t values with the wrong types, at least in code compiled on mingw64. There may be other places, but for now they are only compiled on systems where the existing %d doesn't trigger gcc warnings.
* src/rpc/virnetsocket.c (virNetSocketNew): Use %lld and casting, rather than assuming any particular int type for pid_t. * src/util/command.c (virCommandRunAsync, virPidWait) (virPidAbort): Likewise. (verify): Drop a now stale assertion. --- diff --git a/src/util/command.c b/src/util/command.c index a2d5f84..b752b2a 100644 --- a/src/util/command.c +++ b/src/util/command.c @@ -50,9 +49,6 @@ virReportErrorHelper(VIR_FROM_NONE, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__)
-/* We have quite a bit of changes to make if this doesn't hold. */ -verify(sizeof(pid_t)<= sizeof(int)); -2011-07-12 10:42:41 -0600
Didn't hold that long actually :) (It was added 2011-07-12 10:42:41 -0600 ) ACK, Peter

On 03/02/2012 06:00 AM, Peter Krempa wrote:
On 02/11/2012 12:55 AM, Eric Blake wrote:
Nuke the last vestiges of printing pid_t values with the wrong types, at least in code compiled on mingw64. There may be other places, but for now they are only compiled on systems where the existing %d doesn't trigger gcc warnings.
* src/rpc/virnetsocket.c (virNetSocketNew): Use %lld and casting, rather than assuming any particular int type for pid_t. * src/util/command.c (virCommandRunAsync, virPidWait) (virPidAbort): Likewise. (verify): Drop a now stale assertion. --- diff --git a/src/util/command.c b/src/util/command.c index a2d5f84..b752b2a 100644 --- a/src/util/command.c +++ b/src/util/command.c @@ -50,9 +49,6 @@ virReportErrorHelper(VIR_FROM_NONE, code, __FILE__, \ __FUNCTION__, __LINE__, __VA_ARGS__)
-/* We have quite a bit of changes to make if this doesn't hold. */ -verify(sizeof(pid_t)<= sizeof(int)); -2011-07-12 10:42:41 -0600
Didn't hold that long actually :) (It was added 2011-07-12 10:42:41 -0600 )
ACK,
Thanks; series pushed with 1/2 tweaked as mentioned. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
participants (2)
-
Eric Blake
-
Peter Krempa